diff options
Diffstat (limited to 'drivers')
468 files changed, 5067 insertions, 3077 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 7eb35f4..b423bb1 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_XEN) += xen/ # regulators early, since some subsystems rely on them to initialize obj-$(CONFIG_REGULATOR) += regulator/ -# char/ comes before serial/ etc so that the VT console is the boot-time +# tty/ comes before char/ so that the VT console is the boot-time # default. obj-y += tty/ obj-y += char/ @@ -38,7 +38,6 @@ obj-$(CONFIG_CONNECTOR) += connector/ obj-$(CONFIG_FB_I810) += video/i810/ obj-$(CONFIG_FB_INTEL) += video/intelfb/ -obj-y += serial/ obj-$(CONFIG_PARPORT) += parport/ obj-y += base/ block/ misc/ mfd/ nfc/ obj-$(CONFIG_NUBUS) += nubus/ diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 10c7ad5..2aa042a 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -318,7 +318,7 @@ config ACPI_PCI_SLOT the module will be called pci_slot. config X86_PM_TIMER - bool "Power Management Timer Support" if EMBEDDED + bool "Power Management Timer Support" if EXPERT depends on X86 default y help diff --git a/drivers/acpi/acpica/accommon.h b/drivers/acpi/acpica/accommon.h index 3e50c74..e0ba17f 100644 --- a/drivers/acpi/acpica/accommon.h +++ b/drivers/acpi/acpica/accommon.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index b17d8de..ab87396 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 72e9d5e..eb0b1f8 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acdispat.h b/drivers/acpi/acpica/acdispat.h index 894a0ff..666271b 100644 --- a/drivers/acpi/acpica/acdispat.h +++ b/drivers/acpi/acpica/acdispat.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 70e0b28..41d247d 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 0e4dba0..82a1bd2 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 258d628..e7213be 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index 049e203..3731e1c 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 74000f5..54784bb 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 8d5c9e0..b7491ee 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index d44d3bc..79a598c 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 962a3cc..1055769 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -97,8 +97,6 @@ #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 */ -#define AOPOBJ_MODULE_LEVEL 0x40 /* Method is actually module-level code */ -#define AOPOBJ_MODIFIED_NAMESPACE 0x80 /* Method modified the namespace */ /****************************************************************************** * @@ -175,7 +173,7 @@ struct acpi_object_region { }; struct acpi_object_method { - ACPI_OBJECT_COMMON_HEADER u8 method_flags; + ACPI_OBJECT_COMMON_HEADER u8 info_flags; u8 param_count; u8 sync_level; union acpi_operand_object *mutex; @@ -183,13 +181,21 @@ struct acpi_object_method { union { ACPI_INTERNAL_METHOD implementation; union acpi_operand_object *handler; - } extra; + } dispatch; u32 aml_length; u8 thread_count; acpi_owner_id owner_id; }; +/* Flags for info_flags field above */ + +#define ACPI_METHOD_MODULE_LEVEL 0x01 /* Method is actually module-level code */ +#define ACPI_METHOD_INTERNAL_ONLY 0x02 /* Method is implemented internally (_OSI) */ +#define ACPI_METHOD_SERIALIZED 0x04 /* Method is serialized */ +#define ACPI_METHOD_SERIALIZED_PENDING 0x08 /* Method is to be marked serialized */ +#define ACPI_METHOD_MODIFIED_NAMESPACE 0x10 /* Method modified the namespace */ + /****************************************************************************** * * Objects that can be notified. All share a common notify_info area. diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h index 8c15ff4..bb2ccfa 100644 --- a/drivers/acpi/acpica/acopcode.h +++ b/drivers/acpi/acpica/acopcode.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index d0bb0fd..5ea1e06 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 10998d3..94e73c9 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acresrc.h b/drivers/acpi/acpica/acresrc.h index 528bcba..f08b55b 100644 --- a/drivers/acpi/acpica/acresrc.h +++ b/drivers/acpi/acpica/acresrc.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acstruct.h b/drivers/acpi/acpica/acstruct.h index 6e5dd97..1623b24 100644 --- a/drivers/acpi/acpica/acstruct.h +++ b/drivers/acpi/acpica/acstruct.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h index 62a576e..967f081 100644 --- a/drivers/acpi/acpica/actables.h +++ b/drivers/acpi/acpica/actables.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 72e4183..99c140d 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 1f484ba..f4f0998 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -480,16 +480,10 @@ typedef enum { AML_FIELD_ATTRIB_SMB_BLOCK_CALL = 0x0D } AML_ACCESS_ATTRIBUTE; -/* Bit fields in method_flags byte */ +/* Bit fields in the AML method_flags byte */ #define AML_METHOD_ARG_COUNT 0x07 #define AML_METHOD_SERIALIZED 0x08 #define AML_METHOD_SYNC_LEVEL 0xF0 -/* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ - -#define AML_METHOD_INTERNAL_ONLY 0x01 -#define AML_METHOD_RESERVED1 0x02 -#define AML_METHOD_RESERVED2 0x04 - #endif /* __AMLCODE_H__ */ diff --git a/drivers/acpi/acpica/amlresrc.h b/drivers/acpi/acpica/amlresrc.h index 0e5798f..59122cd 100644 --- a/drivers/acpi/acpica/amlresrc.h +++ b/drivers/acpi/acpica/amlresrc.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 347bee1..34be60c 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c index cc4a38c..a7718bf 100644 --- a/drivers/acpi/acpica/dsinit.c +++ b/drivers/acpi/acpica/dsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index d94dd89..5d79775 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -43,7 +43,6 @@ #include <acpi/acpi.h> #include "accommon.h" -#include "amlcode.h" #include "acdispat.h" #include "acinterp.h" #include "acnamesp.h" @@ -201,7 +200,7 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node, /* * If this method is serialized, we need to acquire the method mutex. */ - if (obj_desc->method.method_flags & AML_METHOD_SERIALIZED) { + if (obj_desc->method.info_flags & ACPI_METHOD_SERIALIZED) { /* * Create a mutex for the method if it is defined to be Serialized * and a mutex has not already been created. We defer the mutex creation @@ -413,8 +412,9 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread, /* Invoke an internal method if necessary */ - if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { - status = obj_desc->method.extra.implementation(next_walk_state); + if (obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) { + status = + obj_desc->method.dispatch.implementation(next_walk_state); if (status == AE_OK) { status = AE_CTRL_TERMINATE; } @@ -579,11 +579,14 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, /* * Delete any namespace objects created anywhere within the - * namespace by the execution of this method. Unless this method - * is a module-level executable code method, in which case we - * want make the objects permanent. + * namespace by the execution of this method. Unless: + * 1) This method is a module-level executable code method, in which + * case we want make the objects permanent. + * 2) There are other threads executing the method, in which case we + * will wait until the last thread has completed. */ - if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { + if (!(method_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) + && (method_desc->method.thread_count == 1)) { /* Delete any direct children of (created by) this method */ @@ -593,12 +596,17 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, /* * Delete any objects that were created by this method * elsewhere in the namespace (if any were created). + * Use of the ACPI_METHOD_MODIFIED_NAMESPACE optimizes the + * deletion such that we don't have to perform an entire + * namespace walk for every control method execution. */ if (method_desc->method. - flags & AOPOBJ_MODIFIED_NAMESPACE) { + info_flags & ACPI_METHOD_MODIFIED_NAMESPACE) { acpi_ns_delete_namespace_by_owner(method_desc-> method. owner_id); + method_desc->method.info_flags &= + ~ACPI_METHOD_MODIFIED_NAMESPACE; } } } @@ -629,19 +637,43 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, * Serialized if it appears that the method is incorrectly written and * does not support multiple thread execution. The best example of this * is if such a method creates namespace objects and blocks. A second - * thread will fail with an AE_ALREADY_EXISTS exception + * thread will fail with an AE_ALREADY_EXISTS exception. * * This code is here because we must wait until the last thread exits - * before creating the synchronization semaphore. + * before marking the method as serialized. */ - if ((method_desc->method.method_flags & AML_METHOD_SERIALIZED) - && (!method_desc->method.mutex)) { - (void)acpi_ds_create_method_mutex(method_desc); + if (method_desc->method. + info_flags & ACPI_METHOD_SERIALIZED_PENDING) { + if (walk_state) { + ACPI_INFO((AE_INFO, + "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error", + walk_state->method_node->name. + ascii)); + } + + /* + * Method tried to create an object twice and was marked as + * "pending serialized". The probable cause is that the method + * cannot handle reentrancy. + * + * The method was created as not_serialized, but it tried to create + * a named object and then blocked, causing the second thread + * entrance to begin and then fail. Workaround this problem by + * marking the method permanently as Serialized when the last + * thread exits here. + */ + method_desc->method.info_flags &= + ~ACPI_METHOD_SERIALIZED_PENDING; + method_desc->method.info_flags |= + ACPI_METHOD_SERIALIZED; + method_desc->method.sync_level = 0; } /* No more threads, we can free the owner_id */ - if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { + if (! + (method_desc->method. + info_flags & ACPI_METHOD_MODULE_LEVEL)) { acpi_ut_release_owner_id(&method_desc->method.owner_id); } } diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 8095306..905ce29 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 8e85f54..f42e17e 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c index 7c0e742..bbecf29 100644 --- a/drivers/acpi/acpica/dsopcode.c +++ b/drivers/acpi/acpica/dsopcode.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c index 15135c2..2c477ce 100644 --- a/drivers/acpi/acpica/dsutils.c +++ b/drivers/acpi/acpica/dsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c index 6b0b5d0..fe40e4c 100644 --- a/drivers/acpi/acpica/dswexec.c +++ b/drivers/acpi/acpica/dswexec.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 140a9d0..52566ff 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswscope.c b/drivers/acpi/acpica/dswscope.c index d1e7017..76a661f 100644 --- a/drivers/acpi/acpica/dswscope.c +++ b/drivers/acpi/acpica/dswscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c index 83155dd..a6c374e 100644 --- a/drivers/acpi/acpica/dswstate.c +++ b/drivers/acpi/acpica/dswstate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index e5e313c..d458b04 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 7c339d3..14988a8 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -471,6 +471,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); if (ACPI_FAILURE(status)) { + ACPI_FREE(local_gpe_event_info); return_VOID; } @@ -478,6 +479,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) if (!acpi_ev_valid_gpe_event(gpe_event_info)) { status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); + ACPI_FREE(local_gpe_event_info); return_VOID; } diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 9acb869..ca2c41a 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index c59dc23..ce9aa9f 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index 10e4774..80a81d0 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index 38bba66..7dc8094 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 98fd210..785a5ee 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 0b47a6d..9659cee 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -590,9 +590,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj, * See acpi_ns_exec_module_code */ if (obj_desc->method. - flags & AOPOBJ_MODULE_LEVEL) { + info_flags & ACPI_METHOD_MODULE_LEVEL) { handler_obj = - obj_desc->method.extra.handler; + obj_desc->method.dispatch.handler; } break; diff --git a/drivers/acpi/acpica/evsci.c b/drivers/acpi/acpica/evsci.c index 8dfbaa9..2ebd40e 100644 --- a/drivers/acpi/acpica/evsci.c +++ b/drivers/acpi/acpica/evsci.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 1226689..e114140 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index 90488c1..c57b5c7 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index 416845b..e9562a7 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index ce9314f..eb73867 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 1883220..745a42b 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c index b73bc50..74162a1 100644 --- a/drivers/acpi/acpica/exconvrt.c +++ b/drivers/acpi/acpica/exconvrt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c index 3c61b48..e7b372d 100644 --- a/drivers/acpi/acpica/excreate.c +++ b/drivers/acpi/acpica/excreate.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -482,13 +482,11 @@ acpi_ex_create_method(u8 * aml_start, obj_desc->method.aml_length = aml_length; /* - * Disassemble the method flags. Split off the Arg Count - * for efficiency + * Disassemble the method flags. Split off the arg_count, Serialized + * flag, and sync_level for efficiency. */ method_flags = (u8) operand[1]->integer.value; - obj_desc->method.method_flags = - (u8) (method_flags & ~AML_METHOD_ARG_COUNT); obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT); @@ -497,6 +495,8 @@ acpi_ex_create_method(u8 * aml_start, * created for this method when it is parsed. */ if (method_flags & AML_METHOD_SERIALIZED) { + obj_desc->method.info_flags = ACPI_METHOD_SERIALIZED; + /* * ACPI 1.0: sync_level = 0 * ACPI 2.0: sync_level = sync_level in method declaration diff --git a/drivers/acpi/acpica/exdebug.c b/drivers/acpi/acpica/exdebug.c index be8c98b..c7a2f1e 100644 --- a/drivers/acpi/acpica/exdebug.c +++ b/drivers/acpi/acpica/exdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index f067bbb..61b8c0e 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -122,7 +122,7 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = { static struct acpi_exdump_info acpi_ex_dump_method[9] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, - {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.info_flags), "Info Flags"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "Parameter Count"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index f17d2ff..0bde223 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 38293fd..6c79c29 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c index 95db4be0..703d88e 100644 --- a/drivers/acpi/acpica/exmisc.c +++ b/drivers/acpi/acpica/exmisc.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c index 6af14e4..be1c56e 100644 --- a/drivers/acpi/acpica/exmutex.c +++ b/drivers/acpi/acpica/exmutex.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exnames.c b/drivers/acpi/acpica/exnames.c index d11e539..49ec049 100644 --- a/drivers/acpi/acpica/exnames.c +++ b/drivers/acpi/acpica/exnames.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c index 84e4d18..236ead1 100644 --- a/drivers/acpi/acpica/exoparg1.c +++ b/drivers/acpi/acpica/exoparg1.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c index 10e104c..2571b4a 100644 --- a/drivers/acpi/acpica/exoparg2.c +++ b/drivers/acpi/acpica/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c index 7a08d23..1b48d9d 100644 --- a/drivers/acpi/acpica/exoparg3.c +++ b/drivers/acpi/acpica/exoparg3.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exoparg6.c b/drivers/acpi/acpica/exoparg6.c index 4b50730..f4a2787 100644 --- a/drivers/acpi/acpica/exoparg6.c +++ b/drivers/acpi/acpica/exoparg6.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c index 7aae29f..cc95e20 100644 --- a/drivers/acpi/acpica/exprep.c +++ b/drivers/acpi/acpica/exprep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c index de17e10..f0d5e14 100644 --- a/drivers/acpi/acpica/exregion.c +++ b/drivers/acpi/acpica/exregion.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c index 1fa4289..55997e4 100644 --- a/drivers/acpi/acpica/exresnte.c +++ b/drivers/acpi/acpica/exresnte.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c index 7ca35ea..db502cd 100644 --- a/drivers/acpi/acpica/exresolv.c +++ b/drivers/acpi/acpica/exresolv.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c index 8c97cfd..e3bb00c 100644 --- a/drivers/acpi/acpica/exresop.c +++ b/drivers/acpi/acpica/exresop.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 1624436..c0c8842 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c index d4af684..a979017 100644 --- a/drivers/acpi/acpica/exstoren.c +++ b/drivers/acpi/acpica/exstoren.c @@ -7,7 +7,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c index e972b66..dc665cc 100644 --- a/drivers/acpi/acpica/exstorob.c +++ b/drivers/acpi/acpica/exstorob.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 675aaa9..df66e7b 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 4093522..8ad9314 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c index b44274a..fc380d3 100644 --- a/drivers/acpi/acpica/hwacpi.c +++ b/drivers/acpi/acpica/hwacpi.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 85c3cbd..f610d88 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwpci.c b/drivers/acpi/acpica/hwpci.c index ad21c7d..050fd22 100644 --- a/drivers/acpi/acpica/hwpci.c +++ b/drivers/acpi/acpica/hwpci.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 5d1273b..55accb7 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -7,7 +7,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 3796811..2ac28bb 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index 1ef8e0b..9c8eb71 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index e1d9c77..5f16058 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 50cc3be..6f98d21 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c index 0cd925b..d93172f 100644 --- a/drivers/acpi/acpica/nsaccess.c +++ b/drivers/acpi/acpica/nsaccess.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -163,9 +163,9 @@ acpi_status acpi_ns_root_initialize(void) #else /* Mark this as a very SPECIAL method */ - obj_desc->method.method_flags = - AML_METHOD_INTERNAL_ONLY; - obj_desc->method.extra.implementation = + obj_desc->method.info_flags = + ACPI_METHOD_INTERNAL_ONLY; + obj_desc->method.dispatch.implementation = acpi_ut_osi_implementation; #endif break; diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index 1e5ff80..1d0ef15 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -234,8 +234,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp * modified the namespace. This is used for cleanup when the * method exits. */ - walk_state->method_desc->method.flags |= - AOPOBJ_MODIFIED_NAMESPACE; + walk_state->method_desc->method.info_flags |= + ACPI_METHOD_MODIFIED_NAMESPACE; } } @@ -341,6 +341,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) { struct acpi_namespace_node *child_node = NULL; u32 level = 1; + acpi_status status; ACPI_FUNCTION_TRACE(ns_delete_namespace_subtree); @@ -348,6 +349,13 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) return_VOID; } + /* Lock namespace for possible update */ + + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + return_VOID; + } + /* * Traverse the tree of objects until we bubble back up * to where we started. @@ -397,6 +405,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node) } } + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); return_VOID; } diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c index a54dc39..b683cc2 100644 --- a/drivers/acpi/acpica/nsdump.c +++ b/drivers/acpi/acpica/nsdump.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -624,9 +624,22 @@ acpi_ns_dump_objects(acpi_object_type type, acpi_owner_id owner_id, acpi_handle start_handle) { struct acpi_walk_info info; + acpi_status status; ACPI_FUNCTION_ENTRY(); + /* + * Just lock the entire namespace for the duration of the dump. + * We don't want any changes to the namespace during this time, + * especially the temporary nodes since we are going to display + * them also. + */ + status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE(status)) { + acpi_os_printf("Could not acquire namespace mutex\n"); + return; + } + info.debug_level = ACPI_LV_TABLES; info.owner_id = owner_id; info.display_type = display_type; @@ -636,6 +649,8 @@ acpi_ns_dump_objects(acpi_object_type type, ACPI_NS_WALK_TEMP_NODES, acpi_ns_dump_one_object, NULL, (void *)&info, NULL); + + (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); } #endif /* ACPI_FUTURE_USAGE */ diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index d2a9792..2ed294b 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index f52829c..c1bd02b 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -389,7 +389,7 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj, * acpi_gbl_root_node->Object is NULL at PASS1. */ if ((type == ACPI_TYPE_DEVICE) && parent_node->object) { - method_obj->method.extra.handler = + method_obj->method.dispatch.handler = parent_node->object->device.handler; } diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 0cac7ec..fd7c638 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index df18be9..5f7dc69 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c index d3104af..d5fa520 100644 --- a/drivers/acpi/acpica/nsnames.c +++ b/drivers/acpi/acpica/nsnames.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 41a9213..3bb8bf1 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index 5808c89..b3234fa 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 7096bcd..9fb03fa 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index d1c1366..1d76ac8 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index 4ef9f43..973883b 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c index 41102a8..28b0d7a 100644 --- a/drivers/acpi/acpica/nssearch.c +++ b/drivers/acpi/acpica/nssearch.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index a7d6ad9..cb1b104 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c index 2cd5be8..345f0c3 100644 --- a/drivers/acpi/acpica/nswalk.c +++ b/drivers/acpi/acpica/nswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index ebef8a7..c53f004 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index b01e45a..3fd4526 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -603,10 +603,9 @@ acpi_status acpi_install_method(u8 *buffer) method_obj->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT); - method_obj->method.method_flags = (u8) - (method_flags & ~AML_METHOD_ARG_COUNT); - if (method_flags & AML_METHOD_SERIALIZED) { + method_obj->method.info_flags = ACPI_METHOD_SERIALIZED; + method_obj->method.sync_level = (u8) ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4); } diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c index a1f04e9..db7660f 100644 --- a/drivers/acpi/acpica/nsxfobj.c +++ b/drivers/acpi/acpica/nsxfobj.c @@ -6,7 +6,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c index 7df1a4c..e1fad0e 100644 --- a/drivers/acpi/acpica/psargs.c +++ b/drivers/acpi/acpica/psargs.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index 2f2e776..01dd70d 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -655,7 +655,7 @@ acpi_ps_link_module_code(union acpi_parse_object *parent_op, method_obj->method.aml_start = aml_start; method_obj->method.aml_length = aml_length; method_obj->method.owner_id = owner_id; - method_obj->method.flags |= AOPOBJ_MODULE_LEVEL; + method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL; /* * Save the parent node in next_object. This is cheating, but we diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c index 2b0c3be..bed08de 100644 --- a/drivers/acpi/acpica/psopcode.c +++ b/drivers/acpi/acpica/psopcode.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c index 8d81542..9bb0cbd 100644 --- a/drivers/acpi/acpica/psparse.c +++ b/drivers/acpi/acpica/psparse.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,7 +55,6 @@ #include "acparser.h" #include "acdispat.h" #include "amlcode.h" -#include "acnamesp.h" #include "acinterp.h" #define _COMPONENT ACPI_PARSER @@ -539,24 +538,16 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) /* Check for possible multi-thread reentrancy problem */ if ((status == AE_ALREADY_EXISTS) && - (!walk_state->method_desc->method.mutex)) { - ACPI_INFO((AE_INFO, - "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error", - walk_state->method_node->name. - ascii)); - + (!(walk_state->method_desc->method. + info_flags & ACPI_METHOD_SERIALIZED))) { /* - * Method tried to create an object twice. The probable cause is - * that the method cannot handle reentrancy. - * - * The method is marked not_serialized, but it tried to create - * a named object, causing the second thread entrance to fail. - * Workaround this problem by marking the method permanently - * as Serialized. + * Method is not serialized and tried to create an object + * twice. The probable cause is that the method cannot + * handle reentrancy. Mark as "pending serialized" now, and + * then mark "serialized" when the last thread exits. */ - walk_state->method_desc->method.method_flags |= - AML_METHOD_SERIALIZED; - walk_state->method_desc->method.sync_level = 0; + walk_state->method_desc->method.info_flags |= + ACPI_METHOD_SERIALIZED_PENDING; } } diff --git a/drivers/acpi/acpica/psscope.c b/drivers/acpi/acpica/psscope.c index 40e2b27..a5faa13 100644 --- a/drivers/acpi/acpica/psscope.c +++ b/drivers/acpi/acpica/psscope.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c index d4b970c..f1464c0 100644 --- a/drivers/acpi/acpica/pstree.c +++ b/drivers/acpi/acpica/pstree.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psutils.c b/drivers/acpi/acpica/psutils.c index fe29eee..7eda785 100644 --- a/drivers/acpi/acpica/psutils.c +++ b/drivers/acpi/acpica/psutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/pswalk.c b/drivers/acpi/acpica/pswalk.c index 8abb962..3312d63 100644 --- a/drivers/acpi/acpica/pswalk.c +++ b/drivers/acpi/acpica/pswalk.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index c42f067..8086805 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,6 @@ #include "acdispat.h" #include "acinterp.h" #include "actables.h" -#include "amlcode.h" #define _COMPONENT ACPI_PARSER ACPI_MODULE_NAME("psxface") @@ -285,15 +284,15 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) goto cleanup; } - if (info->obj_desc->method.flags & AOPOBJ_MODULE_LEVEL) { + if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) { walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL; } /* Invoke an internal method if necessary */ - if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { + if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) { status = - info->obj_desc->method.extra.implementation(walk_state); + info->obj_desc->method.dispatch.implementation(walk_state); info->return_object = walk_state->return_desc; /* Cleanup states */ diff --git a/drivers/acpi/acpica/rsaddr.c b/drivers/acpi/acpica/rsaddr.c index 226c806..9e66f90 100644 --- a/drivers/acpi/acpica/rsaddr.c +++ b/drivers/acpi/acpica/rsaddr.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index d6ebf7e..3a8a89e 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index c80a2ee..4ce6e11 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index f859b03..33db752 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsinfo.c b/drivers/acpi/acpica/rsinfo.c index 1fd868b..f9ea608 100644 --- a/drivers/acpi/acpica/rsinfo.c +++ b/drivers/acpi/acpica/rsinfo.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsio.c b/drivers/acpi/acpica/rsio.c index 33bff17..0c7efef 100644 --- a/drivers/acpi/acpica/rsio.c +++ b/drivers/acpi/acpica/rsio.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsirq.c b/drivers/acpi/acpica/rsirq.c index 545da40..50b8ad2 100644 --- a/drivers/acpi/acpica/rsirq.c +++ b/drivers/acpi/acpica/rsirq.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index 7335f22..1bfcef7 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmemory.c b/drivers/acpi/acpica/rsmemory.c index 887b8ba..7cc6d86 100644 --- a/drivers/acpi/acpica/rsmemory.c +++ b/drivers/acpi/acpica/rsmemory.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsmisc.c b/drivers/acpi/acpica/rsmisc.c index f8cd9e8..410264b 100644 --- a/drivers/acpi/acpica/rsmisc.c +++ b/drivers/acpi/acpica/rsmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsutils.c b/drivers/acpi/acpica/rsutils.c index 491191e..231811e 100644 --- a/drivers/acpi/acpica/rsutils.c +++ b/drivers/acpi/acpica/rsutils.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 9f6a6e7..2ff657a 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c index d2ff432..428d44e 100644 --- a/drivers/acpi/acpica/tbfadt.c +++ b/drivers/acpi/acpica/tbfadt.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbfind.c b/drivers/acpi/acpica/tbfind.c index 989d5c8..a55cb2b 100644 --- a/drivers/acpi/acpica/tbfind.c +++ b/drivers/acpi/acpica/tbfind.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c index 83d7af8..48db094 100644 --- a/drivers/acpi/acpica/tbinstal.c +++ b/drivers/acpi/acpica/tbinstal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index 34f9c2b..0f2d395 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c index 4a8b9e6..4b7085d 100644 --- a/drivers/acpi/acpica/tbxface.c +++ b/drivers/acpi/acpica/tbxface.c @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c index fd2c07d..7eb6c6c 100644 --- a/drivers/acpi/acpica/tbxfroot.c +++ b/drivers/acpi/acpica/tbxfroot.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utalloc.c b/drivers/acpi/acpica/utalloc.c index 8f08962..0a69735 100644 --- a/drivers/acpi/acpica/utalloc.c +++ b/drivers/acpi/acpica/utalloc.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c index 6fef83f..aded299 100644 --- a/drivers/acpi/acpica/utcopy.c +++ b/drivers/acpi/acpica/utcopy.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c index f21c486..a9bcd81 100644 --- a/drivers/acpi/acpica/utdebug.c +++ b/drivers/acpi/acpica/utdebug.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index ed794cd..31f5a78 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 22f59ef..18f73c9 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 508537f..97dd9bb 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index d290632..b679ea6 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index c1b1c80..191b682 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c index b081cd4..f6bb75c 100644 --- a/drivers/acpi/acpica/utlock.c +++ b/drivers/acpi/acpica/utlock.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmath.c b/drivers/acpi/acpica/utmath.c index 49cf7b7..ce481da 100644 --- a/drivers/acpi/acpica/utmath.c +++ b/drivers/acpi/acpica/utmath.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index c7d0e05..c33a852 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c index 199528f..a946c68 100644 --- a/drivers/acpi/acpica/utmutex.c +++ b/drivers/acpi/acpica/utmutex.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c index fd1fa27..188340a 100644 --- a/drivers/acpi/acpica/utobject.c +++ b/drivers/acpi/acpica/utobject.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c index 18c59a8..1fb10cb 100644 --- a/drivers/acpi/acpica/utosi.c +++ b/drivers/acpi/acpica/utosi.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c index 7965919..84e0518 100644 --- a/drivers/acpi/acpica/utresrc.c +++ b/drivers/acpi/acpica/utresrc.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utstate.c b/drivers/acpi/acpica/utstate.c index d35d109..30c21e1 100644 --- a/drivers/acpi/acpica/utstate.c +++ b/drivers/acpi/acpica/utstate.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 1f484c9..98ad125 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/acpica/utxferror.c b/drivers/acpi/acpica/utxferror.c index 6f12e31..916ae09 100644 --- a/drivers/acpi/acpica/utxferror.c +++ b/drivers/acpi/acpica/utxferror.c @@ -5,7 +5,7 @@ ******************************************************************************/ /* - * Copyright (C) 2000 - 2010, Intel Corp. + * Copyright (C) 2000 - 2011, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 68bc227..ac1a599 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -998,7 +998,6 @@ static int acpi_battery_resume(struct acpi_device *device) if (!device) return -EINVAL; battery = acpi_driver_data(device); - acpi_battery_refresh(battery); battery->update_time = 0; acpi_battery_update(battery); return 0; diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c index 54b6ab8..fa5a1df 100644 --- a/drivers/acpi/nvs.c +++ b/drivers/acpi/nvs.c @@ -12,6 +12,7 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/acpi.h> +#include <linux/acpi_io.h> #include <acpi/acpiosxf.h> /* @@ -80,7 +81,7 @@ void suspend_nvs_free(void) free_page((unsigned long)entry->data); entry->data = NULL; if (entry->kaddr) { - acpi_os_unmap_memory(entry->kaddr, entry->size); + iounmap(entry->kaddr); entry->kaddr = NULL; } } @@ -114,8 +115,8 @@ int suspend_nvs_save(void) list_for_each_entry(entry, &nvs_list, node) if (entry->data) { - entry->kaddr = acpi_os_map_memory(entry->phys_start, - entry->size); + entry->kaddr = acpi_os_ioremap(entry->phys_start, + entry->size); if (!entry->kaddr) { suspend_nvs_free(); return -ENOMEM; diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e2dd6de..b093181 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -38,6 +38,7 @@ #include <linux/workqueue.h> #include <linux/nmi.h> #include <linux/acpi.h> +#include <linux/acpi_io.h> #include <linux/efi.h> #include <linux/ioport.h> #include <linux/list.h> @@ -302,9 +303,10 @@ void __iomem *__init_refok acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { struct acpi_ioremap *map, *tmp_map; - unsigned long flags, pg_sz; + unsigned long flags; void __iomem *virt; - phys_addr_t pg_off; + acpi_physical_address pg_off; + acpi_size pg_sz; if (phys > ULONG_MAX) { printk(KERN_ERR PREFIX "Cannot map memory that high\n"); @@ -320,7 +322,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) pg_off = round_down(phys, PAGE_SIZE); pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; - virt = ioremap_cache(pg_off, pg_sz); + virt = acpi_os_ioremap(pg_off, pg_sz); if (!virt) { kfree(map); return NULL; @@ -642,7 +644,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) virt_addr = acpi_map_vaddr_lookup(phys_addr, size); rcu_read_unlock(); if (!virt_addr) { - virt_addr = ioremap_cache(phys_addr, size); + virt_addr = acpi_os_ioremap(phys_addr, size); unmap = 1; } if (!value) @@ -678,7 +680,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) virt_addr = acpi_map_vaddr_lookup(phys_addr, size); rcu_read_unlock(); if (!virt_addr) { - virt_addr = ioremap_cache(phys_addr, size); + virt_addr = acpi_os_ioremap(phys_addr, size); unmap = 1; } diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index fdd3aee..d6a8cd1 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -166,6 +166,7 @@ static void acpi_pm_finish(void) u32 acpi_state = acpi_target_sleep_state; acpi_ec_unblock_transactions(); + suspend_nvs_free(); if (acpi_state == ACPI_STATE_S0) return; @@ -186,7 +187,6 @@ static void acpi_pm_finish(void) */ static void acpi_pm_end(void) { - suspend_nvs_free(); /* * This is necessary in case acpi_pm_finish() is not called during a * failing transition to a sleep state. diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index c6b298d..c2328ae 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -783,7 +783,7 @@ config PATA_PCMCIA config PATA_PLATFORM tristate "Generic platform device PATA support" - depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM + depends on EXPERT || PPC || HAVE_PATA_PLATFORM help This option enables support for generic directly connected ATA devices commonly found on embedded systems. diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c index bca9cb8..487a547 100644 --- a/drivers/atm/idt77105.c +++ b/drivers/atm/idt77105.c @@ -151,7 +151,7 @@ static int fetch_stats(struct atm_dev *dev,struct idt77105_stats __user *arg,int spin_unlock_irqrestore(&idt77105_priv_lock, flags); if (arg == NULL) return 0; - return copy_to_user(arg, &PRIV(dev)->stats, + return copy_to_user(arg, &stats, sizeof(struct idt77105_stats)) ? -EFAULT : 0; } diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index fd96345..d57e8d0 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -70,7 +70,7 @@ config PREVENT_FIRMWARE_BUILD If unsure say Y here. config FW_LOADER - tristate "Userspace firmware loading support" if EMBEDDED + tristate "Userspace firmware loading support" if EXPERT default y ---help--- This option is provided for the case where no in-kernel-tree modules diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 0f175a8..b7980a83 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -5,7 +5,7 @@ menu "Character devices" config VT - bool "Virtual terminal" if EMBEDDED + bool "Virtual terminal" if EXPERT depends on !S390 select INPUT default y @@ -39,13 +39,13 @@ config VT config CONSOLE_TRANSLATIONS depends on VT default y - bool "Enable character translations in console" if EMBEDDED + bool "Enable character translations in console" if EXPERT ---help--- This enables support for font mapping and Unicode translation on virtual consoles. config VT_CONSOLE - bool "Support for console on virtual terminal" if EMBEDDED + bool "Support for console on virtual terminal" if EXPERT depends on VT default y ---help--- @@ -426,10 +426,10 @@ config SGI_MBCS If you have an SGI Altix with an attached SABrick say Y or M here, otherwise say N. -source "drivers/serial/Kconfig" +source "drivers/tty/serial/Kconfig" config UNIX98_PTYS - bool "Unix98 PTY support" if EMBEDDED + bool "Unix98 PTY support" if EXPERT default y ---help--- A pseudo terminal (PTY) is a software device consisting of two @@ -495,7 +495,7 @@ config LEGACY_PTY_COUNT config TTY_PRINTK bool "TTY driver to output user messages via printk" - depends on EMBEDDED + depends on EXPERT default n ---help--- If you say Y here, the support for writing user messages (i.e. diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 1e9dffb..5bc765d 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -30,25 +30,12 @@ obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o -obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o -obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o -obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o -obj-$(CONFIG_HVC_TILE) += hvc_tile.o -obj-$(CONFIG_HVC_DCC) += hvc_dcc.o -obj-$(CONFIG_HVC_BEAT) += hvc_beat.o -obj-$(CONFIG_HVC_DRIVER) += hvc_console.o -obj-$(CONFIG_HVC_IRQ) += hvc_irq.o -obj-$(CONFIG_HVC_XEN) += hvc_xen.o -obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o -obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o -obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MSPEC) += mspec.o obj-$(CONFIG_MMTIMER) += mmtimer.o obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o obj-$(CONFIG_VIOTAPE) += viotape.o -obj-$(CONFIG_HVCS) += hvcs.o obj-$(CONFIG_IBM_BSR) += bsr.o obj-$(CONFIG_SGI_MBCS) += mbcs.o obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 1f46f1c..36e0fa1 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -364,12 +364,14 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, tpm_protected_ordinal_duration[ordinal & TPM_PROTECTED_ORDINAL_MASK]; - if (duration_idx != TPM_UNDEFINED) + if (duration_idx != TPM_UNDEFINED) { duration = chip->vendor.duration[duration_idx]; - if (duration <= 0) + /* if duration is 0, it's because chip->vendor.duration wasn't */ + /* filled yet, so we set the lowest timeout just to give enough */ + /* time for tpm_get_timeouts() to succeed */ + return (duration <= 0 ? HZ : duration); + } else return 2 * 60 * HZ; - else - return duration; } EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index c17a305..dd21df5 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -493,9 +493,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, "1.2 TPM (device-id 0x%X, rev-id %d)\n", vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); - if (is_itpm(to_pnp_dev(dev))) - itpm = 1; - if (itpm) dev_info(dev, "Intel iTPM workaround enabled\n"); @@ -637,6 +634,9 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, else interrupts = 0; + if (is_itpm(pnp_dev)) + itpm = 1; + return tpm_tis_init(&pnp_dev->dev, start, len, irq); } diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index cfb0f52..effe797 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -202,17 +202,21 @@ static int __init init_acpi_pm_clocksource(void) printk(KERN_INFO "PM-Timer had inconsistent results:" " 0x%#llx, 0x%#llx - aborting.\n", value1, value2); + pmtmr_ioport = 0; return -EINVAL; } if (i == ACPI_PM_READ_CHECKS) { printk(KERN_INFO "PM-Timer failed consistency check " " (0x%#llx) - aborting.\n", value1); + pmtmr_ioport = 0; return -ENODEV; } } - if (verify_pmtmr_rate() != 0) + if (verify_pmtmr_rate() != 0){ + pmtmr_ioport = 0; return -ENODEV; + } return clocksource_register_hz(&clocksource_acpi_pm, PMTMR_TICKS_PER_SEC); diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index a8c8d9c..ca8ee80 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -71,7 +71,7 @@ config CPU_FREQ_DEFAULT_GOV_PERFORMANCE config CPU_FREQ_DEFAULT_GOV_POWERSAVE bool "powersave" - depends on EMBEDDED + depends on EXPERT select CPU_FREQ_GOV_POWERSAVE help Use the CPUFreq governor 'powersave' as default. This sets diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 68f942c..0c56989 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -49,15 +49,13 @@ config FIREWIRE_SBP2 configuration section. config FIREWIRE_NET - tristate "IP networking over 1394 (EXPERIMENTAL)" - depends on FIREWIRE && INET && EXPERIMENTAL + tristate "IP networking over 1394" + depends on FIREWIRE && INET help This enables IPv4 over IEEE 1394, providing IP connectivity with other implementations of RFC 2734 as found on several operating systems. Multicast support is currently limited. - NOTE, this driver is not stable yet! - To compile this driver as a module, say M here: The module will be called firewire-net. diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index be04923..24ff355 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c @@ -75,6 +75,8 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; #define BIB_IRMC ((1) << 31) #define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ +#define CANON_OUI 0x000085 + static void generate_config_rom(struct fw_card *card, __be32 *config_rom) { struct fw_descriptor *desc; @@ -284,6 +286,7 @@ static void bm_work(struct work_struct *work) bool root_device_is_running; bool root_device_is_cmc; bool irm_is_1394_1995_only; + bool keep_this_irm; spin_lock_irq(&card->lock); @@ -305,6 +308,10 @@ static void bm_work(struct work_struct *work) irm_is_1394_1995_only = irm_device && irm_device->config_rom && (irm_device->config_rom[2] & 0x000000f0) == 0; + /* Canon MV5i works unreliably if it is not root node. */ + keep_this_irm = irm_device && irm_device->config_rom && + irm_device->config_rom[3] >> 8 == CANON_OUI; + root_id = root_node->node_id; irm_id = card->irm_node->node_id; local_id = card->local_node->node_id; @@ -333,7 +340,7 @@ static void bm_work(struct work_struct *work) goto pick_me; } - if (irm_is_1394_1995_only) { + if (irm_is_1394_1995_only && !keep_this_irm) { new_root_id = local_id; fw_notify("%s, making local node (%02x) root.\n", "IRM is not 1394a compliant", new_root_id); @@ -382,7 +389,7 @@ static void bm_work(struct work_struct *work) spin_lock_irq(&card->lock); - if (rcode != RCODE_COMPLETE) { + if (rcode != RCODE_COMPLETE && !keep_this_irm) { /* * The lock request failed, maybe the IRM * isn't really IRM capable after all. Let's diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index c2e194c..7ed08fd 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -191,6 +191,7 @@ struct fwnet_peer { struct fwnet_device *dev; u64 guid; u64 fifo; + __be32 ip; /* guarded by dev->lock */ struct list_head pd_list; /* received partial datagrams */ @@ -570,6 +571,8 @@ static int fwnet_finish_incoming_packet(struct net_device *net, peer->speed = sspd; if (peer->max_payload > max_payload) peer->max_payload = max_payload; + + peer->ip = arp1394->sip; } spin_unlock_irqrestore(&dev->lock, flags); @@ -1470,6 +1473,7 @@ static int fwnet_add_peer(struct fwnet_device *dev, peer->dev = dev; peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; peer->fifo = FWNET_NO_FIFO_ADDR; + peer->ip = 0; INIT_LIST_HEAD(&peer->pd_list); peer->pdg_size = 0; peer->datagram_label = 0; @@ -1589,10 +1593,13 @@ static int fwnet_remove(struct device *_dev) mutex_lock(&fwnet_device_mutex); + net = dev->netdev; + if (net && peer->ip) + arp_invalidate(net, peer->ip); + fwnet_remove_peer(peer, dev); if (list_empty(&dev->peer_list)) { - net = dev->netdev; unregister_netdev(net); if (dev->local_fifo != FWNET_NO_FIFO_ADDR) diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index e8b6a13..e710424 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -27,7 +27,7 @@ config EDD_OFF using the kernel parameter 'edd={on|skipmbr|off}'. config FIRMWARE_MEMMAP - bool "Add firmware-provided memory map to sysfs" if EMBEDDED + bool "Add firmware-provided memory map to sysfs" if EXPERT default X86 help Add the firmware-provided (unmodified) memory map to /sys/firmware/memmap. diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 64828a7..bea966f 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -23,7 +23,7 @@ config DRM_KMS_HELPER tristate depends on DRM select FB - select FRAMEBUFFER_CONSOLE if !EMBEDDED + select FRAMEBUFFER_CONSOLE if !EXPERT help FB and CRTC helpers for KMS drivers. diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 5c4f9b9..6977a1c 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1533,11 +1533,11 @@ 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) +/* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EXPERT) * 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) +#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EXPERT) static int __init drm_fb_helper_modinit(void) { const char *name = "fbcon"; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 03e3370..f6b9baa 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -928,6 +928,7 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) { + int reread = 0; struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; unsigned long end; @@ -940,9 +941,8 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) * fallback to the slow and accurate path. */ head = intel_read_status_page(ring, 4); - if (head < ring->actual_head) + if (reread) head = I915_READ_HEAD(ring); - ring->actual_head = head; ring->head = head & HEAD_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) @@ -961,6 +961,7 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) msleep(1); if (atomic_read(&dev_priv->mm.wedged)) return -EAGAIN; + reread = 1; } while (!time_after(jiffies, end)); trace_i915_ring_wait_end (dev); return -EBUSY; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index be9087e..5b0abfa 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -47,7 +47,6 @@ struct intel_ring_buffer { struct drm_device *dev; struct drm_i915_gem_object *obj; - u32 actual_head; u32 head; u32 tail; int space; diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 21d6c29..de70959 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -8,7 +8,7 @@ config DRM_NOUVEAU select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB - select FRAMEBUFFER_CONSOLE if !EMBEDDED + select FRAMEBUFFER_CONSOLE if !EXPERT select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT help diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig index 8d0e31a..96c83a9 100644 --- a/drivers/gpu/vga/Kconfig +++ b/drivers/gpu/vga/Kconfig @@ -1,5 +1,5 @@ config VGA_ARB - bool "VGA Arbitration" if EMBEDDED + bool "VGA Arbitration" if EXPERT default y depends on PCI help diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 24cca2f..2560f01 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -62,9 +62,9 @@ config HID_3M_PCT Support for 3M PCT touch screens. config HID_A4TECH - tristate "A4 tech mice" if EMBEDDED + tristate "A4 tech mice" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for A4 tech X5 and WOP-35 / Trust 450L mice. @@ -77,9 +77,9 @@ config HID_ACRUX_FF game controllers. config HID_APPLE - tristate "Apple {i,Power,Mac}Books" if EMBEDDED + tristate "Apple {i,Power,Mac}Books" if EXPERT depends on (USB_HID || BT_HIDP) - default !EMBEDDED + default !EXPERT ---help--- Support for some Apple devices which less or more break HID specification. @@ -88,9 +88,9 @@ config HID_APPLE MacBooks, MacBook Pros and Apple Aluminum. config HID_BELKIN - tristate "Belkin Flip KVM and Wireless keyboard" if EMBEDDED + tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Belkin Flip KVM and Wireless keyboard. @@ -101,16 +101,16 @@ config HID_CANDO Support for Cando dual touch panel. config HID_CHERRY - tristate "Cherry Cymotion keyboard" if EMBEDDED + tristate "Cherry Cymotion keyboard" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Cherry Cymotion keyboard. config HID_CHICONY - tristate "Chicony Tactical pad" if EMBEDDED + tristate "Chicony Tactical pad" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Chicony Tactical pad. @@ -130,9 +130,9 @@ config HID_PRODIKEYS and some additional multimedia keys. config HID_CYPRESS - tristate "Cypress mouse and barcode readers" if EMBEDDED + tristate "Cypress mouse and barcode readers" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for cypress mouse and barcode readers. @@ -174,16 +174,16 @@ config HID_ELECOM Support for the ELECOM BM084 (bluetooth mouse). config HID_EZKEY - tristate "Ezkey BTC 8193 keyboard" if EMBEDDED + tristate "Ezkey BTC 8193 keyboard" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Ezkey BTC 8193 keyboard. config HID_KYE - tristate "Kye/Genius Ergo Mouse" if EMBEDDED + tristate "Kye/Genius Ergo Mouse" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Kye/Genius Ergo Mouse. @@ -212,16 +212,16 @@ config HID_TWINHAN Support for Twinhan IR remote control. config HID_KENSINGTON - tristate "Kensington Slimblade Trackball" if EMBEDDED + tristate "Kensington Slimblade Trackball" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Kensington Slimblade Trackball. config HID_LOGITECH - tristate "Logitech devices" if EMBEDDED + tristate "Logitech devices" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Logitech devices that are not fully compliant with HID standard. @@ -276,9 +276,9 @@ config HID_MAGICMOUSE Apple Wireless "Magic" Mouse. config HID_MICROSOFT - tristate "Microsoft non-fully HID-compliant devices" if EMBEDDED + tristate "Microsoft non-fully HID-compliant devices" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Microsoft devices that are not fully compliant with HID standard. @@ -289,9 +289,9 @@ config HID_MOSART Support for MosArt dual-touch panels. config HID_MONTEREY - tristate "Monterey Genius KB29E keyboard" if EMBEDDED + tristate "Monterey Genius KB29E keyboard" if EXPERT depends on USB_HID - default !EMBEDDED + default !EXPERT ---help--- Support for Monterey Genius KB29E. @@ -365,8 +365,8 @@ config HID_PICOLCD - IR config HID_PICOLCD_FB - bool "Framebuffer support" if EMBEDDED - default !EMBEDDED + bool "Framebuffer support" if EXPERT + default !EXPERT depends on HID_PICOLCD depends on HID_PICOLCD=FB || FB=y select FB_DEFERRED_IO @@ -379,8 +379,8 @@ config HID_PICOLCD_FB frambuffer device. config HID_PICOLCD_BACKLIGHT - bool "Backlight control" if EMBEDDED - default !EMBEDDED + bool "Backlight control" if EXPERT + default !EXPERT depends on HID_PICOLCD depends on HID_PICOLCD=BACKLIGHT_CLASS_DEVICE || BACKLIGHT_CLASS_DEVICE=y ---help--- @@ -388,16 +388,16 @@ config HID_PICOLCD_BACKLIGHT class. config HID_PICOLCD_LCD - bool "Contrast control" if EMBEDDED - default !EMBEDDED + bool "Contrast control" if EXPERT + default !EXPERT depends on HID_PICOLCD depends on HID_PICOLCD=LCD_CLASS_DEVICE || LCD_CLASS_DEVICE=y ---help--- Provide access to PicoLCD's LCD contrast via lcd class. config HID_PICOLCD_LEDS - bool "GPO via leds class" if EMBEDDED - default !EMBEDDED + bool "GPO via leds class" if EXPERT + default !EXPERT depends on HID_PICOLCD depends on HID_PICOLCD=LEDS_CLASS || LEDS_CLASS=y ---help--- diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig index 4edb3be..0f20fd1 100644 --- a/drivers/hid/usbhid/Kconfig +++ b/drivers/hid/usbhid/Kconfig @@ -45,7 +45,7 @@ config USB_HIDDEV If unsure, say Y. menu "USB HID Boot Protocol drivers" - depends on USB!=n && USB_HID!=y && EMBEDDED + depends on USB!=n && USB_HID!=y && EXPERT config USB_KBD tristate "USB HIDBP Keyboard (simple Boot) support" diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 98ccfeb..9827c5e 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -134,7 +134,7 @@ config BLK_DEV_IDECD module will be called ide-cd. config BLK_DEV_IDECD_VERBOSE_ERRORS - bool "Verbose error logging for IDE/ATAPI CDROM driver" if EMBEDDED + bool "Verbose error logging for IDE/ATAPI CDROM driver" if EXPERT depends on BLK_DEV_IDECD default y help diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 7acb32e..1fa091e 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -263,7 +263,7 @@ static void __setup_broadcast_timer(void *arg) clockevents_notify(reason, &cpu); } -static int __cpuinit setup_broadcast_cpuhp_notify(struct notifier_block *n, +static int setup_broadcast_cpuhp_notify(struct notifier_block *n, unsigned long action, void *hcpu) { int hotcpu = (unsigned long)hcpu; @@ -273,15 +273,11 @@ static int __cpuinit setup_broadcast_cpuhp_notify(struct notifier_block *n, smp_call_function_single(hotcpu, __setup_broadcast_timer, (void *)true, 1); break; - case CPU_DOWN_PREPARE: - smp_call_function_single(hotcpu, __setup_broadcast_timer, - (void *)false, 1); - break; } return NOTIFY_OK; } -static struct notifier_block __cpuinitdata setup_broadcast_notifier = { +static struct notifier_block setup_broadcast_notifier = { .notifier_call = setup_broadcast_cpuhp_notify, }; diff --git a/drivers/infiniband/hw/mthca/Kconfig b/drivers/infiniband/hw/mthca/Kconfig index 03efc07..da314c3 100644 --- a/drivers/infiniband/hw/mthca/Kconfig +++ b/drivers/infiniband/hw/mthca/Kconfig @@ -7,7 +7,7 @@ config INFINIBAND_MTHCA ("Tavor") and the MT25208 PCI Express HCA ("Arbel"). config INFINIBAND_MTHCA_DEBUG - bool "Verbose debugging output" if EMBEDDED + bool "Verbose debugging output" if EXPERT depends on INFINIBAND_MTHCA default y ---help--- diff --git a/drivers/infiniband/ulp/ipoib/Kconfig b/drivers/infiniband/ulp/ipoib/Kconfig index 55855ee..cda8eac 100644 --- a/drivers/infiniband/ulp/ipoib/Kconfig +++ b/drivers/infiniband/ulp/ipoib/Kconfig @@ -24,7 +24,7 @@ config INFINIBAND_IPOIB_CM unless you limit mtu for these destinations to 2044. config INFINIBAND_IPOIB_DEBUG - bool "IP-over-InfiniBand debugging" if EMBEDDED + bool "IP-over-InfiniBand debugging" if EXPERT depends on INFINIBAND_IPOIB default y ---help--- diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 07c2cd4..1903c0f 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -6,7 +6,7 @@ menu "Input device support" depends on !S390 config INPUT - tristate "Generic input layer (needed for keyboard, mouse, ...)" if EMBEDDED + tristate "Generic input layer (needed for keyboard, mouse, ...)" if EXPERT default y help Say Y here if you have any input device (mouse, keyboard, tablet, @@ -67,7 +67,7 @@ config INPUT_SPARSEKMAP comment "Userland interfaces" config INPUT_MOUSEDEV - tristate "Mouse interface" if EMBEDDED + tristate "Mouse interface" if EXPERT default y help Say Y here if you want your mouse to be accessible as char devices @@ -150,7 +150,7 @@ config INPUT_EVBUG module will be called evbug. config INPUT_APMPOWER - tristate "Input Power Event -> APM Bridge" if EMBEDDED + tristate "Input Power Event -> APM Bridge" if EXPERT depends on INPUT && APM_EMULATION help Say Y here if you want suspend key events to trigger a user diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 7b3c0b8..4175073 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -2,7 +2,7 @@ # Input core configuration # menuconfig INPUT_KEYBOARD - bool "Keyboards" if EMBEDDED || !X86 + bool "Keyboards" if EXPERT || !X86 default y help Say Y here, and a list of supported keyboards will be displayed. @@ -57,7 +57,7 @@ config KEYBOARD_ATARI module will be called atakbd. config KEYBOARD_ATKBD - tristate "AT keyboard" if EMBEDDED || !X86 + tristate "AT keyboard" if EXPERT || !X86 default y select SERIO select SERIO_LIBPS2 diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index bf5fd7f..9c1e6ee 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -39,7 +39,7 @@ config MOUSE_PS2 module will be called psmouse. config MOUSE_PS2_ALPS - bool "ALPS PS/2 mouse protocol extension" if EMBEDDED + bool "ALPS PS/2 mouse protocol extension" if EXPERT default y depends on MOUSE_PS2 help @@ -49,7 +49,7 @@ config MOUSE_PS2_ALPS If unsure, say Y. config MOUSE_PS2_LOGIPS2PP - bool "Logitech PS/2++ mouse protocol extension" if EMBEDDED + bool "Logitech PS/2++ mouse protocol extension" if EXPERT default y depends on MOUSE_PS2 help @@ -59,7 +59,7 @@ config MOUSE_PS2_LOGIPS2PP If unsure, say Y. config MOUSE_PS2_SYNAPTICS - bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED + bool "Synaptics PS/2 mouse protocol extension" if EXPERT default y depends on MOUSE_PS2 help @@ -69,7 +69,7 @@ config MOUSE_PS2_SYNAPTICS If unsure, say Y. config MOUSE_PS2_LIFEBOOK - bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED + bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT default y depends on MOUSE_PS2 && X86 && DMI help @@ -79,7 +79,7 @@ config MOUSE_PS2_LIFEBOOK If unsure, say Y. config MOUSE_PS2_TRACKPOINT - bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED + bool "IBM Trackpoint PS/2 mouse protocol extension" if EXPERT default y depends on MOUSE_PS2 help diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 307eef7..55f2c22 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -2,7 +2,7 @@ # Input core configuration # config SERIO - tristate "Serial I/O support" if EMBEDDED || !X86 + tristate "Serial I/O support" if EXPERT || !X86 default y help Say Yes here if you have any input device that uses serial I/O to @@ -19,7 +19,7 @@ config SERIO if SERIO config SERIO_I8042 - tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 + tristate "i8042 PC Keyboard controller" if EXPERT || !X86 default y depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN @@ -168,7 +168,7 @@ config SERIO_MACEPS2 module will be called maceps2. config SERIO_LIBPS2 - tristate "PS/2 driver library" if EMBEDDED + tristate "PS/2 driver library" if EXPERT depends on SERIO_I8042 || SERIO_I8042=n help Say Y here if you are using a driver for device connected diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 0c9f4b1..61834ae 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -540,62 +540,62 @@ config TOUCHSCREEN_MC13783 config TOUCHSCREEN_USB_EGALAX default y - bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED + bool "eGalax, eTurboTouch CT-410/510/700 device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_PANJIT default y - bool "PanJit device support" if EMBEDDED + bool "PanJit device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_3M default y - bool "3M/Microtouch EX II series device support" if EMBEDDED + bool "3M/Microtouch EX II series device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_ITM default y - bool "ITM device support" if EMBEDDED + bool "ITM device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_ETURBO default y - bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED + bool "eTurboTouch (non-eGalax compatible) device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_GUNZE default y - bool "Gunze AHL61 device support" if EMBEDDED + bool "Gunze AHL61 device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_DMC_TSC10 default y - bool "DMC TSC-10/25 device support" if EMBEDDED + bool "DMC TSC-10/25 device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_IRTOUCH default y - bool "IRTOUCHSYSTEMS/UNITOP device support" if EMBEDDED + bool "IRTOUCHSYSTEMS/UNITOP device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_IDEALTEK default y - bool "IdealTEK URTC1000 device support" if EMBEDDED + bool "IdealTEK URTC1000 device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_GENERAL_TOUCH default y - bool "GeneralTouch Touchscreen device support" if EMBEDDED + bool "GeneralTouch Touchscreen device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_GOTOP default y - bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED + bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_JASTEC default y - bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EMBEDDED + bool "JASTEC/DigiTech DTR-02U USB touch controller device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_E2I @@ -605,17 +605,17 @@ config TOUCHSCREEN_USB_E2I config TOUCHSCREEN_USB_ZYTRONIC default y - bool "Zytronic controller" if EMBEDDED + bool "Zytronic controller" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_ETT_TC45USB default y - bool "ET&T USB series TC4UM/TC5UH touchscreen controller support" if EMBEDDED + bool "ET&T USB series TC4UM/TC5UH touchscreen controller support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_NEXIO default y - bool "NEXIO/iNexio device support" if EMBEDDED + bool "NEXIO/iNexio device support" if EXPERT depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_TOUCHIT213 diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c index 991d93b..ecc4bf3 100644 --- a/drivers/leds/ledtrig-gpio.c +++ b/drivers/leds/ledtrig-gpio.c @@ -99,7 +99,7 @@ static ssize_t gpio_trig_inverted_show(struct device *dev, struct led_classdev *led = dev_get_drvdata(dev); struct gpio_trig_data *gpio_data = led->trigger_data; - return sprintf(buf, "%s\n", gpio_data->inverted ? "yes" : "no"); + return sprintf(buf, "%u\n", gpio_data->inverted); } static ssize_t gpio_trig_inverted_store(struct device *dev, @@ -107,16 +107,17 @@ static ssize_t gpio_trig_inverted_store(struct device *dev, { struct led_classdev *led = dev_get_drvdata(dev); struct gpio_trig_data *gpio_data = led->trigger_data; - unsigned inverted; + unsigned long inverted; int ret; - ret = sscanf(buf, "%u", &inverted); - if (ret < 1) { - dev_err(dev, "invalid value\n"); + ret = strict_strtoul(buf, 10, &inverted); + if (ret < 0) + return ret; + + if (inverted > 1) return -EINVAL; - } - gpio_data->inverted = !!inverted; + gpio_data->inverted = inverted; /* After inverting, we need to update the LED. */ schedule_work(&gpio_data->work); diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index 04b2212..d21578e 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 b4eb675..9f1659c 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_write(lg_last_cpu, cpu); cpu->last_pages = pages; cpu->changed = CHANGED_ALL; } diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 2e041fd..f3a29f2 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -443,7 +443,7 @@ static int fan_read_reg(int reg, unsigned char *buf, int nb) tries = 0; for (;;) { nr = i2c_master_recv(fcu, buf, nb); - if (nr > 0 || (nr < 0 && nr != ENODEV) || tries >= 100) + if (nr > 0 || (nr < 0 && nr != -ENODEV) || tries >= 100) break; msleep(10); ++tries; @@ -464,7 +464,7 @@ static int fan_write_reg(int reg, const unsigned char *ptr, int nb) tries = 0; for (;;) { nw = i2c_master_send(fcu, buf, nb); - if (nw > 0 || (nw < 0 && nw != EIO) || tries >= 100) + if (nw > 0 || (nw < 0 && nw != -EIO) || tries >= 100) break; msleep(10); ++tries; diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c index 982f000..9f47e38 100644 --- a/drivers/media/common/saa7146_core.c +++ b/drivers/media/common/saa7146_core.c @@ -452,7 +452,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device)); dev->ext = ext; - mutex_init(&dev->lock); + mutex_init(&dev->v4l2_lock); spin_lock_init(&dev->int_slock); spin_lock_init(&dev->slock); diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index e3fedc6..1bd3dd7 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -15,18 +15,15 @@ int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit) } /* is it free? */ - mutex_lock(&dev->lock); if (vv->resources & bit) { DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit)); /* no, someone else uses it */ - mutex_unlock(&dev->lock); return 0; } /* it's free, grab it */ fh->resources |= bit; vv->resources |= bit; DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources)); - mutex_unlock(&dev->lock); return 1; } @@ -37,11 +34,9 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits) BUG_ON((fh->resources & bits) != bits); - mutex_lock(&dev->lock); fh->resources &= ~bits; vv->resources &= ~bits; DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources)); - mutex_unlock(&dev->lock); } @@ -396,7 +391,7 @@ static const struct v4l2_file_operations video_fops = .write = fops_write, .poll = fops_poll, .mmap = fops_mmap, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, }; static void vv_callback(struct saa7146_dev *dev, unsigned long status) @@ -505,6 +500,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, vfd->fops = &video_fops; vfd->ioctl_ops = &dev->ext_vv_data->ops; vfd->release = video_device_release; + vfd->lock = &dev->v4l2_lock; vfd->tvnorms = 0; for (i = 0; i < dev->ext_vv_data->num_stds; i++) vfd->tvnorms |= dev->ext_vv_data->stds[i].id; diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c index 2d4533a..afe8580 100644 --- a/drivers/media/common/saa7146_vbi.c +++ b/drivers/media/common/saa7146_vbi.c @@ -412,7 +412,7 @@ static int vbi_open(struct saa7146_dev *dev, struct file *file) V4L2_BUF_TYPE_VBI_CAPTURE, V4L2_FIELD_SEQ_TB, // FIXME: does this really work? sizeof(struct saa7146_buf), - file, NULL); + file, &dev->v4l2_lock); init_timer(&fh->vbi_read_timeout); fh->vbi_read_timeout.function = vbi_read_timeout; diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 0ac5c61..9aafa4e 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -553,8 +553,6 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f } } - mutex_lock(&dev->lock); - /* ok, accept it */ vv->ov_fb = *fb; vv->ov_fmt = fmt; @@ -563,8 +561,6 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8; DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline)); } - - mutex_unlock(&dev->lock); return 0; } @@ -649,8 +645,6 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) return -EINVAL; } - mutex_lock(&dev->lock); - switch (ctrl->type) { case V4L2_CTRL_TYPE_BOOLEAN: case V4L2_CTRL_TYPE_MENU: @@ -693,7 +687,6 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) /* fixme: we can support changing VFLIP and HFLIP here... */ if (IS_CAPTURE_ACTIVE(fh) != 0) { DEB_D(("V4L2_CID_HFLIP while active capture.\n")); - mutex_unlock(&dev->lock); return -EBUSY; } vv->hflip = c->value; @@ -701,16 +694,13 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) case V4L2_CID_VFLIP: if (IS_CAPTURE_ACTIVE(fh) != 0) { DEB_D(("V4L2_CID_VFLIP while active capture.\n")); - mutex_unlock(&dev->lock); return -EBUSY; } vv->vflip = c->value; break; default: - mutex_unlock(&dev->lock); return -EINVAL; } - mutex_unlock(&dev->lock); if (IS_OVERLAY_ACTIVE(fh) != 0) { saa7146_stop_preview(fh); @@ -902,22 +892,18 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_f err = vidioc_try_fmt_vid_overlay(file, fh, f); if (0 != err) return err; - mutex_lock(&dev->lock); fh->ov.win = f->fmt.win; fh->ov.nclips = f->fmt.win.clipcount; if (fh->ov.nclips > 16) fh->ov.nclips = 16; if (copy_from_user(fh->ov.clips, f->fmt.win.clips, sizeof(struct v4l2_clip) * fh->ov.nclips)) { - mutex_unlock(&dev->lock); return -EFAULT; } /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ fh->ov.fh = fh; - mutex_unlock(&dev->lock); - /* check if our current overlay is active */ if (IS_OVERLAY_ACTIVE(fh) != 0) { saa7146_stop_preview(fh); @@ -976,8 +962,6 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id) } } - mutex_lock(&dev->lock); - for (i = 0; i < dev->ext_vv_data->num_stds; i++) if (*id & dev->ext_vv_data->stds[i].id) break; @@ -988,8 +972,6 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id) found = 1; } - mutex_unlock(&dev->lock); - if (vv->ov_suspend != NULL) { saa7146_start_preview(vv->ov_suspend); vv->ov_suspend = NULL; @@ -1354,7 +1336,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file) V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct saa7146_buf), - file, NULL); + file, &dev->v4l2_lock); return 0; } diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index 78b0895..6fc79f1 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig @@ -34,7 +34,7 @@ config MEDIA_TUNER config MEDIA_TUNER_CUSTOMISE bool "Customize analog and hybrid tuner modules to build" depends on MEDIA_TUNER - default y if EMBEDDED + default y if EXPERT help This allows the user to deselect tuner drivers unnecessary for their hardware from the build. Use this option with care diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index c9062ce..bc6a677 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c @@ -95,8 +95,7 @@ static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close) msleep(20); } else { msg = disable; - tuner_i2c_xfer_send(&priv->i2c_props, msg, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1); buf[2] = msg[1]; buf[2] &= ~0x04; @@ -233,19 +232,22 @@ static void tda8290_set_params(struct dvb_frontend *fe, tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); } + tda8290_i2c_bridge(fe, 1); if (fe->ops.tuner_ops.set_analog_params) fe->ops.tuner_ops.set_analog_params(fe, params); for (i = 0; i < 3; i++) { - tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_pll_stat, 1, &pll_stat, 1); if (pll_stat & 0x80) { - tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); - tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_adc_sat, 1, + &adc_sat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_agc_stat, 1, + &agc_stat, 1); tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); break; } else { @@ -259,20 +261,22 @@ static void tda8290_set_params(struct dvb_frontend *fe, agc_stat, adc_sat, pll_stat & 0x80); tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2); msleep(100); - tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); - tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_agc_stat, 1, &agc_stat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_pll_stat, 1, &pll_stat, 1); if ((agc_stat > 115) || !(pll_stat & 0x80)) { tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", agc_stat, pll_stat & 0x80); if (priv->cfg.agcf) priv->cfg.agcf(fe); msleep(100); - tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); - tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_agc_stat, 1, + &agc_stat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_pll_stat, 1, + &pll_stat, 1); if((agc_stat > 115) || !(pll_stat & 0x80)) { tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2); @@ -284,10 +288,12 @@ static void tda8290_set_params(struct dvb_frontend *fe, /* l/ l' deadlock? */ if(priv->tda8290_easy_mode & 0x60) { - tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); - tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_adc_sat, 1, + &adc_sat, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &addr_pll_stat, 1, + &pll_stat, 1); if ((adc_sat > 20) || !(pll_stat & 0x80)) { tuner_dbg("trying to resolve SECAM L deadlock\n"); tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2); @@ -307,8 +313,7 @@ static void tda8295_power(struct dvb_frontend *fe, int enable) struct tda8290_priv *priv = fe->analog_demod_priv; unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */ - tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); if (enable) buf[1] = 0x01; @@ -323,8 +328,7 @@ static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable) struct tda8290_priv *priv = fe->analog_demod_priv; unsigned char buf[] = { 0x01, 0x00 }; - tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); if (enable) buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */ @@ -353,8 +357,7 @@ static void tda8295_agc1_out(struct dvb_frontend *fe, int enable) struct tda8290_priv *priv = fe->analog_demod_priv; unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */ - tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); if (enable) buf[1] &= ~0x40; @@ -370,10 +373,10 @@ static void tda8295_agc2_out(struct dvb_frontend *fe, int enable) unsigned char set_gpio_cf[] = { 0x44, 0x00 }; unsigned char set_gpio_val[] = { 0x46, 0x00 }; - tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1); - tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &set_gpio_cf[0], 1, &set_gpio_cf[1], 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &set_gpio_val[0], 1, &set_gpio_val[1], 1); set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */ @@ -392,8 +395,7 @@ static int tda8295_has_signal(struct dvb_frontend *fe) unsigned char hvpll_stat = 0x26; unsigned char ret; - tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1); return (ret & 0x01) ? 65535 : 0; } @@ -413,8 +415,8 @@ static void tda8295_set_params(struct dvb_frontend *fe, tda8295_power(fe, 1); tda8295_agc1_out(fe, 1); - tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1); - tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + &blanking_mode[0], 1, &blanking_mode[1], 1); tda8295_set_video_std(fe); @@ -447,8 +449,8 @@ static int tda8290_has_signal(struct dvb_frontend *fe) unsigned char i2c_get_afc[1] = { 0x1B }; unsigned char afc = 0; - tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc)); - tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1); + tuner_i2c_xfer_send_recv(&priv->i2c_props, + i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1); return (afc & 0x80)? 65535:0; } @@ -654,20 +656,26 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) static int tda8290_probe(struct tuner_i2c_props *i2c_props) { #define TDA8290_ID 0x89 - unsigned char tda8290_id[] = { 0x1f, 0x00 }; + u8 reg = 0x1f, id; + struct i2c_msg msg_read[] = { + { .addr = 0x4b, .flags = 0, .len = 1, .buf = ® }, + { .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id }, + }; /* detect tda8290 */ - tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1); - tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1); + if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { + printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n", + __func__, reg); + return -ENODEV; + } - if (tda8290_id[1] == TDA8290_ID) { + if (id == TDA8290_ID) { if (debug) printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", __func__, i2c_adapter_id(i2c_props->adap), i2c_props->addr); return 0; } - return -ENODEV; } @@ -675,16 +683,23 @@ static int tda8295_probe(struct tuner_i2c_props *i2c_props) { #define TDA8295_ID 0x8a #define TDA8295C2_ID 0x8b - unsigned char tda8295_id[] = { 0x2f, 0x00 }; + u8 reg = 0x2f, id; + struct i2c_msg msg_read[] = { + { .addr = 0x4b, .flags = 0, .len = 1, .buf = ® }, + { .addr = 0x4b, .flags = I2C_M_RD, .len = 1, .buf = &id }, + }; - /* detect tda8295 */ - tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1); - tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); + /* detect tda8290 */ + if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { + printk(KERN_WARNING "%s: tda8290 couldn't read register 0x%02x\n", + __func__, reg); + return -ENODEV; + } - if ((tda8295_id[1] & 0xfe) == TDA8295_ID) { + if ((id & 0xfe) == TDA8295_ID) { if (debug) printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n", - __func__, (tda8295_id[1] == TDA8295_ID) ? + __func__, (id == TDA8295_ID) ? "tda8295c1" : "tda8295c2", i2c_adapter_id(i2c_props->adap), i2c_props->addr); @@ -740,9 +755,11 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, sizeof(struct analog_demod_ops)); } - if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) && - (tda829x_find_tuner(fe) < 0)) - goto fail; + if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) { + tda8295_power(fe, 1); + if (tda829x_find_tuner(fe) < 0) + goto fail; + } switch (priv->ver) { case TDA8290: @@ -786,6 +803,8 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, return fe; fail: + memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops)); + tda829x_release(fe); return NULL; } @@ -809,8 +828,8 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) int i; /* rule out tda9887, which would return the same byte repeatedly */ - tuner_i2c_xfer_send(&i2c_props, soft_reset, 1); - tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE); + tuner_i2c_xfer_send_recv(&i2c_props, + soft_reset, 1, buf, PROBE_BUFFER_SIZE); for (i = 1; i < PROBE_BUFFER_SIZE; i++) { if (buf[i] != buf[0]) break; @@ -827,13 +846,12 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) /* fall back to old probing method */ tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2); tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); - tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); - tuner_i2c_xfer_recv(&i2c_props, &data, 1); + tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1); if (data == 0) { tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2); tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); - tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); - tuner_i2c_xfer_recv(&i2c_props, &data, 1); + tuner_i2c_xfer_send_recv(&i2c_props, + &addr_dto_lsb, 1, &data, 1); if (data == 0x7b) { return 0; } diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 8ca48f7..98ffb40 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -514,8 +514,8 @@ struct dib0700_rc_response { union { u16 system16; struct { - u8 system; u8 not_system; + u8 system; }; }; u8 data; @@ -575,7 +575,7 @@ static void dib0700_rc_urb_completion(struct urb *purb) if ((poll_reply->system ^ poll_reply->not_system) != 0xff) { deb_data("NEC extended protocol\n"); /* NEC extended code - 24 bits */ - keycode = poll_reply->system16 << 8 | poll_reply->data; + keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data; } else { deb_data("NEC normal protocol\n"); /* normal NEC code - 16 bits */ @@ -587,7 +587,7 @@ static void dib0700_rc_urb_completion(struct urb *purb) deb_data("RC5 protocol\n"); /* RC5 Protocol */ toggle = poll_reply->report_id; - keycode = poll_reply->system16 << 8 | poll_reply->data; + keycode = poll_reply->system << 8 | poll_reply->data; break; } diff --git a/drivers/media/dvb/firewire/firedtv-rc.c b/drivers/media/dvb/firewire/firedtv-rc.c index fcf3828..f82d4a9 100644 --- a/drivers/media/dvb/firewire/firedtv-rc.c +++ b/drivers/media/dvb/firewire/firedtv-rc.c @@ -172,7 +172,8 @@ void fdtv_unregister_rc(struct firedtv *fdtv) void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) { - u16 *keycode = fdtv->remote_ctrl_dev->keycode; + struct input_dev *idev = fdtv->remote_ctrl_dev; + u16 *keycode = idev->keycode; if (code >= 0x0300 && code <= 0x031f) code = keycode[code - 0x0300]; @@ -188,6 +189,8 @@ void fdtv_handle_rc(struct firedtv *fdtv, unsigned int code) return; } - input_report_key(fdtv->remote_ctrl_dev, code, 1); - input_report_key(fdtv->remote_ctrl_dev, code, 0); + input_report_key(idev, code, 1); + input_sync(idev); + input_report_key(idev, code, 0); + input_sync(idev); } diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index ef3e43a..b8519ba 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -1,7 +1,7 @@ config DVB_FE_CUSTOMISE bool "Customise the frontend modules to build" depends on DVB_CORE - default y if EMBEDDED + default y if EXPERT help This allows the user to select/deselect frontend drivers for their hardware from the build. diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c index ce22205..ba25fa0 100644 --- a/drivers/media/dvb/frontends/af9013.c +++ b/drivers/media/dvb/frontends/af9013.c @@ -334,11 +334,11 @@ static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) if_sample_freq = 3300000; /* 3.3 MHz */ break; case BANDWIDTH_7_MHZ: - if_sample_freq = 3800000; /* 3.8 MHz */ + if_sample_freq = 3500000; /* 3.5 MHz */ break; case BANDWIDTH_8_MHZ: default: - if_sample_freq = 4300000; /* 4.3 MHz */ + if_sample_freq = 4000000; /* 4.0 MHz */ break; } } else if (state->config.tuner == AF9013_TUNER_TDA18218) { diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c index 6360c68..6c2e929 100644 --- a/drivers/media/dvb/frontends/ix2505v.c +++ b/drivers/media/dvb/frontends/ix2505v.c @@ -311,7 +311,7 @@ struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, return fe; error: - ix2505v_release(fe); + kfree(state); return NULL; } EXPORT_SYMBOL(ix2505v_attach); diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c index d3ad3e7..cc4acd2 100644 --- a/drivers/media/dvb/frontends/mb86a20s.c +++ b/drivers/media/dvb/frontends/mb86a20s.c @@ -43,6 +43,8 @@ struct mb86a20s_state { const struct mb86a20s_config *config; struct dvb_frontend frontend; + + bool need_init; }; struct regdata { @@ -318,7 +320,7 @@ static int mb86a20s_i2c_writereg(struct mb86a20s_state *state, rc = i2c_transfer(state->i2c, &msg, 1); if (rc != 1) { - printk("%s: writereg rcor(rc == %i, reg == 0x%02x," + printk("%s: writereg error (rc == %i, reg == 0x%02x," " data == 0x%02x)\n", __func__, rc, reg, data); return rc; } @@ -353,7 +355,7 @@ static int mb86a20s_i2c_readreg(struct mb86a20s_state *state, rc = i2c_transfer(state->i2c, msg, 2); if (rc != 2) { - rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc); + rc("%s: reg=0x%x (error=%d)\n", __func__, reg, rc); return rc; } @@ -382,23 +384,31 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) /* Initialize the frontend */ rc = mb86a20s_writeregdata(state, mb86a20s_init); if (rc < 0) - return rc; + goto err; if (!state->config->is_serial) { regD5 &= ~1; rc = mb86a20s_writereg(state, 0x50, 0xd5); if (rc < 0) - return rc; + goto err; rc = mb86a20s_writereg(state, 0x51, regD5); if (rc < 0) - return rc; + goto err; } if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - return 0; +err: + if (rc < 0) { + state->need_init = true; + printk(KERN_INFO "mb86a20s: Init failed. Will try again later\n"); + } else { + state->need_init = false; + dprintk("Initialization succeded.\n"); + } + return rc; } static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength) @@ -485,8 +495,22 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + dprintk("Calling tuner set parameters\n"); fe->ops.tuner_ops.set_params(fe, p); + /* + * Make it more reliable: if, for some reason, the initial + * device initialization doesn't happen, initialize it when + * a SBTVD parameters are adjusted. + * + * Unfortunately, due to a hard to track bug at tda829x/tda18271, + * the agc callback logic is not called during DVB attach time, + * causing mb86a20s to not be initialized with Kworld SBTVD. + * So, this hack is needed, in order to make Kworld SBTVD to work. + */ + if (state->need_init) + mb86a20s_initfe(fe); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception); diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index 122c728..9fc1dd0 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c @@ -277,7 +277,7 @@ static int dvb_ca_ioctl(struct file *file, unsigned int cmd, void *parg) { ca_slot_info_t *info=(ca_slot_info_t *)parg; - if (info->num > 1) + if (info->num < 0 || info->num > 1) return -EINVAL; av7110->ci_slot[info->num].num = info->num; av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 3c5a473..ecdffa6 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -151,20 +151,6 @@ config RADIO_GEMTEK_PROBE following ports will be probed: 0x20c, 0x30c, 0x24c, 0x34c, 0x248 and 0x28c. -config RADIO_GEMTEK_PCI - tristate "GemTek PCI Radio Card support" - depends on VIDEO_V4L2 && PCI - ---help--- - Choose Y here if you have this PCI FM radio card. - - In order to control your radio card, you will need to use programs - that are compatible with the Video for Linux API. Information on - this API and pointers to "v4l" programs may be found at - <file:Documentation/video4linux/API.html>. - - To compile this driver as a module, choose M here: the - module will be called radio-gemtek-pci. - config RADIO_MAXIRADIO tristate "Guillemot MAXI Radio FM 2000 radio" depends on VIDEO_V4L2 && PCI diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index d297074..717656d 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_RADIO_MAXIRADIO) += radio-maxiradio.o obj-$(CONFIG_RADIO_RTRACK) += radio-aimslab.o obj-$(CONFIG_RADIO_ZOLTRIX) += radio-zoltrix.o obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o -obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 6cc5d13..4ce10db 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -31,6 +31,7 @@ #include <linux/module.h> /* Modules */ #include <linux/init.h> /* Initdata */ #include <linux/ioport.h> /* request_region */ +#include <linux/delay.h> /* msleep */ #include <linux/videodev2.h> /* kernel radio structs */ #include <linux/version.h> /* for KERNEL_VERSION MACRO */ #include <linux/io.h> /* outb, outb_p */ diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c deleted file mode 100644 index 28fa85b..0000000 --- a/drivers/media/radio/radio-gemtek-pci.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - *************************************************************************** - * - * radio-gemtek-pci.c - Gemtek PCI Radio driver - * (C) 2001 Vladimir Shebordaev <vshebordaev@mail.ru> - * - *************************************************************************** - * - * 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. - * - *************************************************************************** - * - * Gemtek Corp still silently refuses to release any specifications - * of their multimedia devices, so the protocol still has to be - * reverse engineered. - * - * The v4l code was inspired by Jonas Munsin's Gemtek serial line - * radio device driver. - * - * Please, let me know if this piece of code was useful :) - * - * TODO: multiple device support and portability were not tested - * - * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> - * - *************************************************************************** - */ - -#include <linux/types.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/videodev2.h> -#include <linux/errno.h> -#include <linux/version.h> /* for KERNEL_VERSION MACRO */ -#include <linux/io.h> -#include <linux/slab.h> -#include <media/v4l2-device.h> -#include <media/v4l2-ioctl.h> - -MODULE_AUTHOR("Vladimir Shebordaev <vshebordaev@mail.ru>"); -MODULE_DESCRIPTION("The video4linux driver for the Gemtek PCI Radio Card"); -MODULE_LICENSE("GPL"); - -static int nr_radio = -1; -static int mx = 1; - -module_param(mx, bool, 0); -MODULE_PARM_DESC(mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not"); -module_param(nr_radio, int, 0); -MODULE_PARM_DESC(nr_radio, "video4linux device number to use"); - -#define RADIO_VERSION KERNEL_VERSION(0, 0, 2) - -#ifndef PCI_VENDOR_ID_GEMTEK -#define PCI_VENDOR_ID_GEMTEK 0x5046 -#endif - -#ifndef PCI_DEVICE_ID_GEMTEK_PR103 -#define PCI_DEVICE_ID_GEMTEK_PR103 0x1001 -#endif - -#ifndef GEMTEK_PCI_RANGE_LOW -#define GEMTEK_PCI_RANGE_LOW (87*16000) -#endif - -#ifndef GEMTEK_PCI_RANGE_HIGH -#define GEMTEK_PCI_RANGE_HIGH (108*16000) -#endif - -struct gemtek_pci { - struct v4l2_device v4l2_dev; - struct video_device vdev; - struct mutex lock; - struct pci_dev *pdev; - - u32 iobase; - u32 length; - - u32 current_frequency; - u8 mute; -}; - -static inline struct gemtek_pci *to_gemtek_pci(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct gemtek_pci, v4l2_dev); -} - -static inline u8 gemtek_pci_out(u16 value, u32 port) -{ - outw(value, port); - - return (u8)value; -} - -#define _b0(v) (*((u8 *)&v)) - -static void __gemtek_pci_cmd(u16 value, u32 port, u8 *last_byte, int keep) -{ - u8 byte = *last_byte; - - if (!value) { - if (!keep) - value = (u16)port; - byte &= 0xfd; - } else - byte |= 2; - - _b0(value) = byte; - outw(value, port); - byte |= 1; - _b0(value) = byte; - outw(value, port); - byte &= 0xfe; - _b0(value) = byte; - outw(value, port); - - *last_byte = byte; -} - -static inline void gemtek_pci_nil(u32 port, u8 *last_byte) -{ - __gemtek_pci_cmd(0x00, port, last_byte, false); -} - -static inline void gemtek_pci_cmd(u16 cmd, u32 port, u8 *last_byte) -{ - __gemtek_pci_cmd(cmd, port, last_byte, true); -} - -static void gemtek_pci_setfrequency(struct gemtek_pci *card, unsigned long frequency) -{ - int i; - u32 value = frequency / 200 + 856; - u16 mask = 0x8000; - u8 last_byte; - u32 port = card->iobase; - - mutex_lock(&card->lock); - card->current_frequency = frequency; - last_byte = gemtek_pci_out(0x06, port); - - i = 0; - do { - gemtek_pci_nil(port, &last_byte); - i++; - } while (i < 9); - - i = 0; - do { - gemtek_pci_cmd(value & mask, port, &last_byte); - mask >>= 1; - i++; - } while (i < 16); - - outw(0x10, port); - mutex_unlock(&card->lock); -} - - -static void gemtek_pci_mute(struct gemtek_pci *card) -{ - mutex_lock(&card->lock); - outb(0x1f, card->iobase); - card->mute = true; - mutex_unlock(&card->lock); -} - -static void gemtek_pci_unmute(struct gemtek_pci *card) -{ - if (card->mute) { - gemtek_pci_setfrequency(card, card->current_frequency); - card->mute = false; - } -} - -static int gemtek_pci_getsignal(struct gemtek_pci *card) -{ - int sig; - - mutex_lock(&card->lock); - sig = (inb(card->iobase) & 0x08) ? 0 : 1; - mutex_unlock(&card->lock); - return sig; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *v) -{ - struct gemtek_pci *card = video_drvdata(file); - - strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver)); - strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card)); - snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(card->pdev)); - v->version = RADIO_VERSION; - v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; - return 0; -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *v) -{ - struct gemtek_pci *card = video_drvdata(file); - - if (v->index > 0) - return -EINVAL; - - strlcpy(v->name, "FM", sizeof(v->name)); - v->type = V4L2_TUNER_RADIO; - v->rangelow = GEMTEK_PCI_RANGE_LOW; - v->rangehigh = GEMTEK_PCI_RANGE_HIGH; - v->rxsubchans = V4L2_TUNER_SUB_MONO; - v->capability = V4L2_TUNER_CAP_LOW; - v->audmode = V4L2_TUNER_MODE_MONO; - v->signal = 0xffff * gemtek_pci_getsignal(card); - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *v) -{ - return v->index ? -EINVAL : 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct gemtek_pci *card = video_drvdata(file); - - if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) - return -EINVAL; - if (f->frequency < GEMTEK_PCI_RANGE_LOW || - f->frequency > GEMTEK_PCI_RANGE_HIGH) - return -EINVAL; - gemtek_pci_setfrequency(card, f->frequency); - card->mute = false; - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct gemtek_pci *card = video_drvdata(file); - - if (f->tuner != 0) - return -EINVAL; - f->type = V4L2_TUNER_RADIO; - f->frequency = card->current_frequency; - return 0; -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_AUDIO_MUTE: - return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535); - } - return -EINVAL; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct gemtek_pci *card = video_drvdata(file); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - ctrl->value = card->mute; - return 0; - case V4L2_CID_AUDIO_VOLUME: - if (card->mute) - ctrl->value = 0; - else - ctrl->value = 65535; - return 0; - } - return -EINVAL; -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct gemtek_pci *card = video_drvdata(file); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value) - gemtek_pci_mute(card); - else - gemtek_pci_unmute(card); - return 0; - case V4L2_CID_AUDIO_VOLUME: - if (ctrl->value) - gemtek_pci_unmute(card); - else - gemtek_pci_mute(card); - return 0; - } - return -EINVAL; -} - -static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) -{ - *i = 0; - return 0; -} - -static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) -{ - return i ? -EINVAL : 0; -} - -static int vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - a->index = 0; - strlcpy(a->name, "Radio", sizeof(a->name)); - a->capability = V4L2_AUDCAP_STEREO; - return 0; -} - -static int vidioc_s_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - return a->index ? -EINVAL : 0; -} - -enum { - GEMTEK_PR103 -}; - -static char *card_names[] __devinitdata = { - "GEMTEK_PR103" -}; - -static struct pci_device_id gemtek_pci_id[] = -{ - { PCI_VENDOR_ID_GEMTEK, PCI_DEVICE_ID_GEMTEK_PR103, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, GEMTEK_PR103 }, - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, gemtek_pci_id); - -static const struct v4l2_file_operations gemtek_pci_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_audio = vidioc_g_audio, - .vidioc_s_audio = vidioc_s_audio, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, -}; - -static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) -{ - struct gemtek_pci *card; - struct v4l2_device *v4l2_dev; - int res; - - card = kzalloc(sizeof(struct gemtek_pci), GFP_KERNEL); - if (card == NULL) { - dev_err(&pdev->dev, "out of memory\n"); - return -ENOMEM; - } - - v4l2_dev = &card->v4l2_dev; - mutex_init(&card->lock); - card->pdev = pdev; - - strlcpy(v4l2_dev->name, "gemtek_pci", sizeof(v4l2_dev->name)); - - res = v4l2_device_register(&pdev->dev, v4l2_dev); - if (res < 0) { - v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); - kfree(card); - return res; - } - - if (pci_enable_device(pdev)) - goto err_pci; - - card->iobase = pci_resource_start(pdev, 0); - card->length = pci_resource_len(pdev, 0); - - if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) { - v4l2_err(v4l2_dev, "i/o port already in use\n"); - goto err_pci; - } - - strlcpy(card->vdev.name, v4l2_dev->name, sizeof(card->vdev.name)); - card->vdev.v4l2_dev = v4l2_dev; - card->vdev.fops = &gemtek_pci_fops; - card->vdev.ioctl_ops = &gemtek_pci_ioctl_ops; - card->vdev.release = video_device_release_empty; - video_set_drvdata(&card->vdev, card); - - gemtek_pci_mute(card); - - if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) - goto err_video; - - v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", - pdev->revision, card->iobase, card->iobase + card->length - 1); - - return 0; - -err_video: - release_region(card->iobase, card->length); - -err_pci: - v4l2_device_unregister(v4l2_dev); - kfree(card); - return -ENODEV; -} - -static void __devexit gemtek_pci_remove(struct pci_dev *pdev) -{ - struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev); - struct gemtek_pci *card = to_gemtek_pci(v4l2_dev); - - video_unregister_device(&card->vdev); - v4l2_device_unregister(v4l2_dev); - - release_region(card->iobase, card->length); - - if (mx) - gemtek_pci_mute(card); - - kfree(card); -} - -static struct pci_driver gemtek_pci_driver = { - .name = "gemtek_pci", - .id_table = gemtek_pci_id, - .probe = gemtek_pci_probe, - .remove = __devexit_p(gemtek_pci_remove), -}; - -static int __init gemtek_pci_init(void) -{ - return pci_register_driver(&gemtek_pci_driver); -} - -static void __exit gemtek_pci_exit(void) -{ - pci_unregister_driver(&gemtek_pci_driver); -} - -module_init(gemtek_pci_init); -module_exit(gemtek_pci_exit); diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 6459a22..5c2a905 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -77,8 +77,8 @@ MODULE_PARM_DESC(debug, "activates debug info"); /* TEA5757 pin mappings */ static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16; -#define FREQ_LO (50 * 16000) -#define FREQ_HI (150 * 16000) +#define FREQ_LO (87 * 16000) +#define FREQ_HI (108 * 16000) #define FREQ_IF 171200 /* 10.7*16000 */ #define FREQ_STEP 200 /* 12.5*16 */ diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c index dd6bd36..7ecc8e6 100644 --- a/drivers/media/radio/radio-wl1273.c +++ b/drivers/media/radio/radio-wl1273.c @@ -1407,7 +1407,7 @@ static const struct v4l2_file_operations wl1273_fops = { .read = wl1273_fm_fops_read, .write = wl1273_fm_fops_write, .poll = wl1273_fm_fops_poll, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, .open = wl1273_fm_fops_open, .release = wl1273_fm_fops_release, }; diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index ac76dfe..60c176f 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c @@ -357,7 +357,8 @@ int si470x_start(struct si470x_device *radio) goto done; /* sysconfig 1 */ - radio->registers[SYSCONFIG1] = SYSCONFIG1_DE; + radio->registers[SYSCONFIG1] = + (de << 11) & SYSCONFIG1_DE; /* DE*/ retval = si470x_set_register(radio, SYSCONFIG1); if (retval < 0) goto done; @@ -687,12 +688,8 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, /* driver constants */ strcpy(tuner->name, "FM"); tuner->type = V4L2_TUNER_RADIO; -#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO; -#else - tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; -#endif /* range limits */ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) { @@ -718,12 +715,10 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, tuner->rxsubchans = V4L2_TUNER_SUB_MONO; else tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; -#if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE) /* If there is a reliable method of detecting an RDS channel, then this code should check for that before setting this RDS subchannel. */ tuner->rxsubchans |= V4L2_TUNER_SUB_RDS; -#endif /* mono/stereo selector */ if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 0) diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index 80b3c31..1ac4913 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -446,27 +446,27 @@ static void ene_rx_setup(struct ene_device *dev) select_timeout: if (dev->rx_fan_input_inuse) { - dev->rdev->rx_resolution = MS_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN); + dev->rdev->rx_resolution = US_TO_NS(ENE_FW_SAMPLE_PERIOD_FAN); /* Fan input doesn't support timeouts, it just ends the input with a maximum sample */ dev->rdev->min_timeout = dev->rdev->max_timeout = - MS_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK * + US_TO_NS(ENE_FW_SMPL_BUF_FAN_MSK * ENE_FW_SAMPLE_PERIOD_FAN); } else { - dev->rdev->rx_resolution = MS_TO_NS(sample_period); + dev->rdev->rx_resolution = US_TO_NS(sample_period); /* Theoreticly timeout is unlimited, but we cap it * because it was seen that on one device, it * would stop sending spaces after around 250 msec. * Besides, this is close to 2^32 anyway and timeout is u32. */ - dev->rdev->min_timeout = MS_TO_NS(127 * sample_period); - dev->rdev->max_timeout = MS_TO_NS(200000); + dev->rdev->min_timeout = US_TO_NS(127 * sample_period); + dev->rdev->max_timeout = US_TO_NS(200000); } if (dev->hw_learning_and_tx_capable) - dev->rdev->tx_resolution = MS_TO_NS(sample_period); + dev->rdev->tx_resolution = US_TO_NS(sample_period); if (dev->rdev->timeout > dev->rdev->max_timeout) dev->rdev->timeout = dev->rdev->max_timeout; @@ -801,7 +801,7 @@ static irqreturn_t ene_isr(int irq, void *data) dbg("RX: %d (%s)", hw_sample, pulse ? "pulse" : "space"); - ev.duration = MS_TO_NS(hw_sample); + ev.duration = US_TO_NS(hw_sample); ev.pulse = pulse; ir_raw_event_store_with_filter(dev->rdev, &ev); } @@ -821,7 +821,7 @@ static void ene_setup_default_settings(struct ene_device *dev) dev->learning_mode_enabled = learning_mode_force; /* Set reasonable default timeout */ - dev->rdev->timeout = MS_TO_NS(150000); + dev->rdev->timeout = US_TO_NS(150000); } /* Upload all hardware settings at once. Used at load and resume time */ @@ -1004,6 +1004,10 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) /* validate resources */ error = -ENODEV; + /* init these to -1, as 0 is valid for both */ + dev->hw_io = -1; + dev->irq = -1; + if (!pnp_port_valid(pnp_dev, 0) || pnp_port_len(pnp_dev, 0) < ENE_IO_SIZE) goto error; @@ -1072,6 +1076,8 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) rdev->input_name = "ENE eHome Infrared Remote Transceiver"; } + dev->rdev = rdev; + ene_rx_setup_hw_buffer(dev); ene_setup_default_settings(dev); ene_setup_hw_settings(dev); @@ -1083,7 +1089,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) if (error < 0) goto error; - dev->rdev = rdev; ene_notice("driver has been succesfully loaded"); return 0; error: diff --git a/drivers/media/rc/ene_ir.h b/drivers/media/rc/ene_ir.h index c179baf..337a41d 100644 --- a/drivers/media/rc/ene_ir.h +++ b/drivers/media/rc/ene_ir.h @@ -201,8 +201,6 @@ #define dbg_verbose(format, ...) __dbg(2, format, ## __VA_ARGS__) #define dbg_regs(format, ...) __dbg(3, format, ## __VA_ARGS__) -#define MS_TO_NS(msec) ((msec) * 1000) - struct ene_device { struct pnp_dev *pnp_dev; struct rc_dev *rdev; diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 6811512..e7dc6b4 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -988,7 +988,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) int retval; struct imon_context *ictx = rc->priv; struct device *dev = ictx->dev; - bool pad_mouse; unsigned char ir_proto_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; @@ -1000,29 +999,20 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) case RC_TYPE_RC6: dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); ir_proto_packet[0] = 0x01; - pad_mouse = false; break; case RC_TYPE_UNKNOWN: case RC_TYPE_OTHER: dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); - if (pad_stabilize && !nomouse) - pad_mouse = true; - else { + if (!pad_stabilize) dev_dbg(dev, "PAD stabilize functionality disabled\n"); - pad_mouse = false; - } /* ir_proto_packet[0] = 0x00; // already the default */ rc_type = RC_TYPE_OTHER; break; default: dev_warn(dev, "Unsupported IR protocol specified, overriding " "to iMON IR protocol\n"); - if (pad_stabilize && !nomouse) - pad_mouse = true; - else { + if (!pad_stabilize) dev_dbg(dev, "PAD stabilize functionality disabled\n"); - pad_mouse = false; - } /* ir_proto_packet[0] = 0x00; // already the default */ rc_type = RC_TYPE_OTHER; break; @@ -1035,7 +1025,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) goto out; ictx->rc_type = rc_type; - ictx->pad_mouse = pad_mouse; + ictx->pad_mouse = false; out: return retval; @@ -1517,7 +1507,7 @@ static void imon_incoming_packet(struct imon_context *ictx, spin_unlock_irqrestore(&ictx->kc_lock, flags); return; } else { - ictx->pad_mouse = 0; + ictx->pad_mouse = false; dev_dbg(dev, "mouse mode disabled, passing key value\n"); } } @@ -1756,7 +1746,6 @@ static void imon_get_ffdc_type(struct imon_context *ictx) printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte); ictx->display_type = detected_display_type; - ictx->rdev->allowed_protos = allowed_protos; ictx->rc_type = allowed_protos; } @@ -1839,10 +1828,6 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) rdev->allowed_protos = RC_TYPE_OTHER | RC_TYPE_RC6; /* iMON PAD or MCE */ rdev->change_protocol = imon_ir_change_protocol; rdev->driver_name = MOD_NAME; - if (ictx->rc_type == RC_TYPE_RC6) - rdev->map_name = RC_MAP_IMON_MCE; - else - rdev->map_name = RC_MAP_IMON_PAD; /* Enable front-panel buttons and/or knobs */ memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet)); @@ -1851,11 +1836,18 @@ static struct rc_dev *imon_init_rdev(struct imon_context *ictx) if (ret) dev_info(ictx->dev, "panel buttons/knobs setup failed\n"); - if (ictx->product == 0xffdc) + if (ictx->product == 0xffdc) { imon_get_ffdc_type(ictx); + rdev->allowed_protos = ictx->rc_type; + } imon_set_display_type(ictx); + if (ictx->rc_type == RC_TYPE_RC6) + rdev->map_name = RC_MAP_IMON_MCE; + else + rdev->map_name = RC_MAP_IMON_PAD; + ret = rc_register_device(rdev); if (ret < 0) { dev_err(ictx->dev, "remote input dev register failed\n"); @@ -2108,18 +2100,6 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) goto find_endpoint_failed; } - ictx->idev = imon_init_idev(ictx); - if (!ictx->idev) { - dev_err(dev, "%s: input device setup failed\n", __func__); - goto idev_setup_failed; - } - - ictx->rdev = imon_init_rdev(ictx); - if (!ictx->rdev) { - dev_err(dev, "%s: rc device setup failed\n", __func__); - goto rdev_setup_failed; - } - usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0, usb_rcvintpipe(ictx->usbdev_intf0, ictx->rx_endpoint_intf0->bEndpointAddress), @@ -2133,13 +2113,25 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) goto urb_submit_failed; } + ictx->idev = imon_init_idev(ictx); + if (!ictx->idev) { + dev_err(dev, "%s: input device setup failed\n", __func__); + goto idev_setup_failed; + } + + ictx->rdev = imon_init_rdev(ictx); + if (!ictx->rdev) { + dev_err(dev, "%s: rc device setup failed\n", __func__); + goto rdev_setup_failed; + } + return ictx; -urb_submit_failed: - rc_unregister_device(ictx->rdev); rdev_setup_failed: input_unregister_device(ictx->idev); idev_setup_failed: + usb_kill_urb(ictx->rx_urb_intf0); +urb_submit_failed: find_endpoint_failed: mutex_unlock(&ictx->lock); usb_free_urb(tx_urb); diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 185badd..73230ff 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c @@ -233,7 +233,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_handle); /* used internally by the sysfs interface */ u64 -ir_raw_get_allowed_protocols() +ir_raw_get_allowed_protocols(void) { u64 protocols; mutex_lock(&ir_raw_handler_lock); diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c index c59851b..7a5f530 100644 --- a/drivers/media/rc/keymaps/rc-dib0700-nec.c +++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c @@ -19,35 +19,35 @@ static struct rc_map_table dib0700_nec_table[] = { /* Key codes for the Pixelview SBTVD remote */ - { 0x8613, KEY_MUTE }, - { 0x8612, KEY_POWER }, - { 0x8601, KEY_1 }, - { 0x8602, KEY_2 }, - { 0x8603, KEY_3 }, - { 0x8604, KEY_4 }, - { 0x8605, KEY_5 }, - { 0x8606, KEY_6 }, - { 0x8607, KEY_7 }, - { 0x8608, KEY_8 }, - { 0x8609, KEY_9 }, - { 0x8600, KEY_0 }, - { 0x860d, KEY_CHANNELUP }, - { 0x8619, KEY_CHANNELDOWN }, - { 0x8610, KEY_VOLUMEUP }, - { 0x860c, KEY_VOLUMEDOWN }, + { 0x866b13, KEY_MUTE }, + { 0x866b12, KEY_POWER }, + { 0x866b01, KEY_1 }, + { 0x866b02, KEY_2 }, + { 0x866b03, KEY_3 }, + { 0x866b04, KEY_4 }, + { 0x866b05, KEY_5 }, + { 0x866b06, KEY_6 }, + { 0x866b07, KEY_7 }, + { 0x866b08, KEY_8 }, + { 0x866b09, KEY_9 }, + { 0x866b00, KEY_0 }, + { 0x866b0d, KEY_CHANNELUP }, + { 0x866b19, KEY_CHANNELDOWN }, + { 0x866b10, KEY_VOLUMEUP }, + { 0x866b0c, KEY_VOLUMEDOWN }, - { 0x860a, KEY_CAMERA }, - { 0x860b, KEY_ZOOM }, - { 0x861b, KEY_BACKSPACE }, - { 0x8615, KEY_ENTER }, + { 0x866b0a, KEY_CAMERA }, + { 0x866b0b, KEY_ZOOM }, + { 0x866b1b, KEY_BACKSPACE }, + { 0x866b15, KEY_ENTER }, - { 0x861d, KEY_UP }, - { 0x861e, KEY_DOWN }, - { 0x860e, KEY_LEFT }, - { 0x860f, KEY_RIGHT }, + { 0x866b1d, KEY_UP }, + { 0x866b1e, KEY_DOWN }, + { 0x866b0e, KEY_LEFT }, + { 0x866b0f, KEY_RIGHT }, - { 0x8618, KEY_RECORD }, - { 0x861a, KEY_STOP }, + { 0x866b18, KEY_RECORD }, + { 0x866b1a, KEY_STOP }, /* Key codes for the EvolutePC TVWay+ remote */ { 0x7a00, KEY_MENU }, diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 0fef6ef..079353e 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -48,7 +48,6 @@ #define USB_BUFLEN 32 /* USB reception buffer length */ #define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ #define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ -#define MS_TO_NS(msec) ((msec) * 1000) /* MCE constants */ #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ @@ -858,7 +857,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) ir->rem--; rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) - * MS_TO_NS(MCE_TIME_UNIT); + * MS_TO_US(MCE_TIME_UNIT); dev_dbg(ir->dev, "Storing %s with duration %d\n", rawir.pulse ? "pulse" : "space", diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index eb875af..aa02160 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -78,7 +78,7 @@ config VIDEO_FIXED_MINOR_RANGES config VIDEO_HELPER_CHIPS_AUTO bool "Autoselect pertinent encoders/decoders and other helper chips" - default y if !EMBEDDED + default y if !EXPERT ---help--- Most video cards may require additional modules to encode or decode audio/video standards. This option will autoselect @@ -141,15 +141,6 @@ config VIDEO_TDA9840 To compile this driver as a module, choose M here: the module will be called tda9840. -config VIDEO_TDA9875 - tristate "Philips TDA9875 audio processor" - depends on VIDEO_V4L2 && I2C - ---help--- - Support for tda9875 audio decoder chip found on some bt8xx boards. - - To compile this driver as a module, choose M here: the - module will be called tda9875. - config VIDEO_TEA6415C tristate "Philips TEA6415C audio processor" depends on I2C diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 81e38cb..a509d31 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -27,7 +27,6 @@ obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o -obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index f318b51..d2327db 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -303,11 +303,22 @@ static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0); } +static int adv7175_s_power(struct v4l2_subdev *sd, int on) +{ + if (on) + adv7175_write(sd, 0x01, 0x00); + else + adv7175_write(sd, 0x01, 0x78); + + return 0; +} + /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops adv7175_core_ops = { .g_chip_ident = adv7175_g_chip_ident, .init = adv7175_init, + .s_power = adv7175_s_power, }; static const struct v4l2_subdev_video_ops adv7175_video_ops = { diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index 49efcf6..7f58756 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -1373,7 +1373,6 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x1800, .audio_mode_gpio= fv2000s_audio, .no_msp34xx = 1, - .no_tda9875 = 1, .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1511,7 +1510,6 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x09, .needs_tvaudio = 1, .no_msp34xx = 1, - .no_tda9875 = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1550,7 +1548,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask2 = 0x07ff, .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3), .no_msp34xx = 1, - .no_tda9875 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .muxsel_hook = rv605_muxsel, @@ -1686,7 +1683,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, [BTTV_BOARD_OSPREY1x0_848] = { @@ -1699,7 +1695,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, @@ -1714,7 +1709,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, [BTTV_BOARD_OSPREY1x1] = { @@ -1727,7 +1721,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, [BTTV_BOARD_OSPREY1x1_SVID] = { @@ -1740,7 +1733,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, [BTTV_BOARD_OSPREY2xx] = { @@ -1753,7 +1745,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, @@ -1768,7 +1759,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, [BTTV_BOARD_OSPREY2x0] = { @@ -1781,7 +1771,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, [BTTV_BOARD_OSPREY500] = { @@ -1794,7 +1783,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, [BTTV_BOARD_OSPREY540] = { @@ -1805,7 +1793,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, @@ -1820,7 +1807,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */ }, [BTTV_BOARD_IDS_EAGLE] = { @@ -1835,7 +1821,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2), .muxsel_hook = eagle_muxsel, .no_msp34xx = 1, - .no_tda9875 = 1, .pll = PLL_28, }, [BTTV_BOARD_PINNACLESAT] = { @@ -1846,7 +1831,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .muxsel = MUXSEL(3, 1), .pll = PLL_28, @@ -1897,7 +1881,6 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .muxsel = MUXSEL(2, 0, 1), .pll = PLL_28, @@ -1970,7 +1953,6 @@ struct tvcard bttv_tvcards[] = { /* Tuner, CVid, SVid, CVid over SVid connector */ .muxsel = MUXSEL(2, 3, 1, 1), .gpiomask = 0, - .no_tda9875 = 1, .no_tda7432 = 1, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -2017,7 +1999,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0), .muxsel_hook = xguard_muxsel, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, }, @@ -2029,7 +2010,6 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .muxsel = MUXSEL(2, 3, 1, 0), .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -2134,7 +2114,6 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, /* card has no svhs */ .needs_tvaudio = 0, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .gpiomask = 0x00, .muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), @@ -2156,7 +2135,6 @@ struct tvcard bttv_tvcards[] = { [BTTV_BOARD_TWINHAN_DST] = { .name = "Twinhan DST + clones", .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2171,7 +2149,6 @@ struct tvcard bttv_tvcards[] = { /* Vid In, SVid In, Vid over SVid in connector */ .muxsel = MUXSEL(3, 1, 1, 3), .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2226,7 +2203,6 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .muxsel = MUXSEL(2, 3, 1, 0), .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, @@ -2278,7 +2254,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/ .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, /*878A input is always MUX0, see above.*/ .muxsel = MUXSEL(2, 2, 2, 2), @@ -2302,7 +2277,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, }, [BTTV_BOARD_AVDVBT_771] = { /* Wolfram Joost <wojo@frokaschwei.de> */ @@ -2313,7 +2287,6 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .muxsel = MUXSEL(3, 3), .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, .has_dvb = 1, @@ -2329,7 +2302,6 @@ struct tvcard bttv_tvcards[] = { .svhs = 1, .muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */ .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -2393,7 +2365,6 @@ struct tvcard bttv_tvcards[] = { /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */ .name = "DViCO FusionHDTV DVB-T Lite", .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, .no_video = 1, @@ -2440,7 +2411,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), .pll = PLL_28, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2478,7 +2448,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .no_msp34xx = 1, .no_tda7432 = 1, - .no_tda9875 = 1, .muxsel_hook = kodicom4400r_muxsel, }, [BTTV_BOARD_KODICOM_4400R_SL] = { @@ -2500,7 +2469,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .no_msp34xx = 1, .no_tda7432 = 1, - .no_tda9875 = 1, .muxsel_hook = kodicom4400r_muxsel, }, /* ---- card 0x86---------------------------------- */ @@ -2530,7 +2498,6 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, .gpiomute = 0x00c00007, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .has_dvb = 1, }, @@ -2630,7 +2597,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, /* ---- card 0x8d ---------------------------------- */ @@ -2658,7 +2624,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 100000, 100002, 100002, 100000 }, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .pll = PLL_28, .tuner_type = TUNER_TNF_5335MF, @@ -2674,7 +2639,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x0f, /* old: 7 */ .muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */ .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2732,7 +2696,6 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, .gpiomute = 0x00c00007, .no_msp34xx = 1, - .no_tda9875 = 1, .no_tda7432 = 1, }, /* ---- card 0x95---------------------------------- */ @@ -2874,7 +2837,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .no_msp34xx = 1, .no_tda7432 = 1, - .no_tda9875 = 1, .muxsel_hook = gv800s_muxsel, }, [BTTV_BOARD_GEOVISION_GV800S_SL] = { @@ -2899,7 +2861,6 @@ struct tvcard bttv_tvcards[] = { .pll = PLL_28, .no_msp34xx = 1, .no_tda7432 = 1, - .no_tda9875 = 1, .muxsel_hook = gv800s_muxsel, }, [BTTV_BOARD_PV183] = { diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index fd62bf1..c633359 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h @@ -234,7 +234,6 @@ struct tvcard { /* i2c audio flags */ unsigned int no_msp34xx:1; - unsigned int no_tda9875:1; unsigned int no_tda7432:1; unsigned int needs_tvaudio:1; unsigned int msp34xx_alt:1; diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 49f1b8f..55ffd60 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2001,6 +2001,11 @@ static int cafe_pci_probe(struct pci_dev *pdev, .min_width = 320, .min_height = 240, }; + struct i2c_board_info ov7670_info = { + .type = "ov7670", + .addr = 0x42, + .platform_data = &sensor_cfg, + }; /* * Start putting together one of our big camera structures. @@ -2062,9 +2067,9 @@ static int cafe_pci_probe(struct pci_dev *pdev, if (dmi_check_system(olpc_xo1_dmi)) sensor_cfg.clock_speed = 45; - cam->sensor_addr = 0x42; - cam->sensor = v4l2_i2c_new_subdev_cfg(&cam->v4l2_dev, &cam->i2c_adapter, - "ov7670", 0, &sensor_cfg, cam->sensor_addr, NULL); + cam->sensor_addr = ov7670_info.addr; + cam->sensor = v4l2_i2c_new_subdev_board(&cam->v4l2_dev, &cam->i2c_adapter, + &ov7670_info, NULL); if (cam->sensor == NULL) { ret = -ENODEV; goto out_smbus; diff --git a/drivers/media/video/cpia2/cpia2.h b/drivers/media/video/cpia2/cpia2.h index 916c13d..6d6d184 100644 --- a/drivers/media/video/cpia2/cpia2.h +++ b/drivers/media/video/cpia2/cpia2.h @@ -378,7 +378,7 @@ struct cpia2_fh { struct camera_data { /* locks */ - struct mutex busy_lock; /* guard against SMP multithreading */ + struct mutex v4l2_lock; /* serialize file operations */ struct v4l2_prio_state prio; /* camera status */ diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index 9606bc0..aaffca8 100644 --- a/drivers/media/video/cpia2/cpia2_core.c +++ b/drivers/media/video/cpia2/cpia2_core.c @@ -2247,7 +2247,7 @@ struct camera_data *cpia2_init_camera_struct(void) cam->present = 1; - mutex_init(&cam->busy_lock); + mutex_init(&cam->v4l2_lock); init_waitqueue_head(&cam->wq_stream); return cam; @@ -2365,9 +2365,9 @@ long cpia2_read(struct camera_data *cam, char __user *buf, unsigned long count, int noblock) { struct framebuf *frame; - if (!count) { + + if (!count) return 0; - } if (!buf) { ERR("%s: buffer NULL\n",__func__); @@ -2379,17 +2379,12 @@ long cpia2_read(struct camera_data *cam, return -EINVAL; } - /* make this _really_ smp and multithread-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) - return -ERESTARTSYS; - if (!cam->present) { LOG("%s: camera removed\n",__func__); - mutex_unlock(&cam->busy_lock); return 0; /* EOF */ } - if(!cam->streaming) { + if (!cam->streaming) { /* Start streaming */ cpia2_usb_stream_start(cam, cam->params.camera_state.stream_mode); @@ -2398,42 +2393,31 @@ long cpia2_read(struct camera_data *cam, /* Copy cam->curbuff in case it changes while we're processing */ frame = cam->curbuff; if (noblock && frame->status != FRAME_READY) { - mutex_unlock(&cam->busy_lock); return -EAGAIN; } - if(frame->status != FRAME_READY) { - mutex_unlock(&cam->busy_lock); + if (frame->status != FRAME_READY) { + mutex_unlock(&cam->v4l2_lock); wait_event_interruptible(cam->wq_stream, !cam->present || (frame = cam->curbuff)->status == FRAME_READY); + mutex_lock(&cam->v4l2_lock); if (signal_pending(current)) return -ERESTARTSYS; - /* make this _really_ smp and multithread-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) { - return -ERESTARTSYS; - } - if(!cam->present) { - mutex_unlock(&cam->busy_lock); + if (!cam->present) return 0; - } } /* copy data to user space */ - if (frame->length > count) { - mutex_unlock(&cam->busy_lock); + if (frame->length > count) return -EFAULT; - } - if (copy_to_user(buf, frame->data, frame->length)) { - mutex_unlock(&cam->busy_lock); + if (copy_to_user(buf, frame->data, frame->length)) return -EFAULT; - } count = frame->length; frame->status = FRAME_EMPTY; - mutex_unlock(&cam->busy_lock); return count; } @@ -2447,17 +2431,13 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, { unsigned int status=0; - if(!cam) { + if (!cam) { ERR("%s: Internal error, camera_data not found!\n",__func__); return POLLERR; } - mutex_lock(&cam->busy_lock); - - if(!cam->present) { - mutex_unlock(&cam->busy_lock); + if (!cam->present) return POLLHUP; - } if(!cam->streaming) { /* Start streaming */ @@ -2465,16 +2445,13 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp, cam->params.camera_state.stream_mode); } - mutex_unlock(&cam->busy_lock); poll_wait(filp, &cam->wq_stream, wait); - mutex_lock(&cam->busy_lock); if(!cam->present) status = POLLHUP; else if(cam->curbuff->status == FRAME_READY) status = POLLIN | POLLRDNORM; - mutex_unlock(&cam->busy_lock); return status; } @@ -2496,29 +2473,19 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma) DBG("mmap offset:%ld size:%ld\n", start_offset, size); - /* make this _really_ smp-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) - return -ERESTARTSYS; - - if (!cam->present) { - mutex_unlock(&cam->busy_lock); + if (!cam->present) return -ENODEV; - } if (size > cam->frame_size*cam->num_frames || (start_offset % cam->frame_size) != 0 || - (start_offset+size > cam->frame_size*cam->num_frames)) { - mutex_unlock(&cam->busy_lock); + (start_offset+size > cam->frame_size*cam->num_frames)) return -EINVAL; - } pos = ((unsigned long) (cam->frame_buffer)) + start_offset; while (size > 0) { page = kvirt_to_pa(pos); - if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) { - mutex_unlock(&cam->busy_lock); + if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) return -EAGAIN; - } start += PAGE_SIZE; pos += PAGE_SIZE; if (size > PAGE_SIZE) @@ -2528,7 +2495,5 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma) } cam->mmapped = true; - mutex_unlock(&cam->busy_lock); return 0; } - diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 7edf80b..9bad398 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -238,59 +238,40 @@ static struct v4l2_queryctrl controls[] = { static int cpia2_open(struct file *file) { struct camera_data *cam = video_drvdata(file); - int retval = 0; + struct cpia2_fh *fh; if (!cam) { ERR("Internal error, camera_data not found!\n"); return -ENODEV; } - if(mutex_lock_interruptible(&cam->busy_lock)) - return -ERESTARTSYS; - - if(!cam->present) { - retval = -ENODEV; - goto err_return; - } + if (!cam->present) + return -ENODEV; - if (cam->open_count > 0) { - goto skip_init; - } + if (cam->open_count == 0) { + if (cpia2_allocate_buffers(cam)) + return -ENOMEM; - if (cpia2_allocate_buffers(cam)) { - retval = -ENOMEM; - goto err_return; - } + /* reset the camera */ + if (cpia2_reset_camera(cam) < 0) + return -EIO; - /* reset the camera */ - if (cpia2_reset_camera(cam) < 0) { - retval = -EIO; - goto err_return; + cam->APP_len = 0; + cam->COM_len = 0; } - cam->APP_len = 0; - cam->COM_len = 0; - -skip_init: - { - struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL); - if(!fh) { - retval = -ENOMEM; - goto err_return; - } - file->private_data = fh; - fh->prio = V4L2_PRIORITY_UNSET; - v4l2_prio_open(&cam->prio, &fh->prio); - fh->mmapped = 0; - } + fh = kmalloc(sizeof(*fh), GFP_KERNEL); + if (!fh) + return -ENOMEM; + file->private_data = fh; + fh->prio = V4L2_PRIORITY_UNSET; + v4l2_prio_open(&cam->prio, &fh->prio); + fh->mmapped = 0; ++cam->open_count; cpia2_dbg_dump_registers(cam); - -err_return: - mutex_unlock(&cam->busy_lock); - return retval; + return 0; } /****************************************************************************** @@ -304,15 +285,11 @@ static int cpia2_close(struct file *file) struct camera_data *cam = video_get_drvdata(dev); struct cpia2_fh *fh = file->private_data; - mutex_lock(&cam->busy_lock); - if (cam->present && - (cam->open_count == 1 - || fh->prio == V4L2_PRIORITY_RECORD - )) { + (cam->open_count == 1 || fh->prio == V4L2_PRIORITY_RECORD)) { cpia2_usb_stream_stop(cam); - if(cam->open_count == 1) { + if (cam->open_count == 1) { /* save camera state for later open */ cpia2_save_camera_state(cam); @@ -321,26 +298,21 @@ static int cpia2_close(struct file *file) } } - { - if(fh->mmapped) - cam->mmapped = 0; - v4l2_prio_close(&cam->prio, fh->prio); - file->private_data = NULL; - kfree(fh); - } + if (fh->mmapped) + cam->mmapped = 0; + v4l2_prio_close(&cam->prio, fh->prio); + file->private_data = NULL; + kfree(fh); if (--cam->open_count == 0) { cpia2_free_buffers(cam); if (!cam->present) { video_unregister_device(dev); - mutex_unlock(&cam->busy_lock); kfree(cam); return 0; } } - mutex_unlock(&cam->busy_lock); - return 0; } @@ -405,11 +377,11 @@ static int sync(struct camera_data *cam, int frame_nr) return 0; } - mutex_unlock(&cam->busy_lock); + mutex_unlock(&cam->v4l2_lock); wait_event_interruptible(cam->wq_stream, !cam->streaming || frame->status == FRAME_READY); - mutex_lock(&cam->busy_lock); + mutex_lock(&cam->v4l2_lock); if (signal_pending(current)) return -ERESTARTSYS; if(!cam->present) @@ -1293,11 +1265,11 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) if(frame < 0) { /* Wait for a frame to become available */ struct framebuf *cb=cam->curbuff; - mutex_unlock(&cam->busy_lock); + mutex_unlock(&cam->v4l2_lock); wait_event_interruptible(cam->wq_stream, !cam->present || (cb=cam->curbuff)->status == FRAME_READY); - mutex_lock(&cam->busy_lock); + mutex_lock(&cam->v4l2_lock); if (signal_pending(current)) return -ERESTARTSYS; if(!cam->present) @@ -1337,14 +1309,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (!cam) return -ENOTTY; - /* make this _really_ smp-safe */ - if (mutex_lock_interruptible(&cam->busy_lock)) - return -ERESTARTSYS; - - if (!cam->present) { - mutex_unlock(&cam->busy_lock); + if (!cam->present) return -ENODEV; - } /* Priority check */ switch (cmd) { @@ -1352,10 +1318,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct cpia2_fh *fh = file->private_data; retval = v4l2_prio_check(&cam->prio, fh->prio); - if(retval) { - mutex_unlock(&cam->busy_lock); + if (retval) return retval; - } break; } default: @@ -1529,7 +1493,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) break; } - mutex_unlock(&cam->busy_lock); return retval; } @@ -1596,7 +1559,7 @@ static const struct v4l2_file_operations cpia2_fops = { .release = cpia2_close, .read = cpia2_v4l_read, .poll = cpia2_v4l_poll, - .ioctl = cpia2_ioctl, + .unlocked_ioctl = cpia2_ioctl, .mmap = cpia2_mmap, }; @@ -1620,6 +1583,7 @@ int cpia2_register_camera(struct camera_data *cam) memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template)); video_set_drvdata(cam->vdev, cam); + cam->vdev->lock = &cam->v4l2_lock; reset_camera_struct_v4l(cam); diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 133ec2b..944af8a 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -664,7 +664,7 @@ static int __devinit cx18_create_in_workq(struct cx18 *cx) { snprintf(cx->in_workq_name, sizeof(cx->in_workq_name), "%s-in", cx->v4l2_dev.name); - cx->in_work_queue = create_singlethread_workqueue(cx->in_workq_name); + cx->in_work_queue = alloc_ordered_workqueue(cx->in_workq_name, 0); if (cx->in_work_queue == NULL) { CX18_ERR("Unable to create incoming mailbox handler thread\n"); return -ENOMEM; @@ -672,18 +672,6 @@ static int __devinit cx18_create_in_workq(struct cx18 *cx) return 0; } -static int __devinit cx18_create_out_workq(struct cx18 *cx) -{ - snprintf(cx->out_workq_name, sizeof(cx->out_workq_name), "%s-out", - cx->v4l2_dev.name); - cx->out_work_queue = create_workqueue(cx->out_workq_name); - if (cx->out_work_queue == NULL) { - CX18_ERR("Unable to create outgoing mailbox handler threads\n"); - return -ENOMEM; - } - return 0; -} - static void __devinit cx18_init_in_work_orders(struct cx18 *cx) { int i; @@ -710,15 +698,9 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) mutex_init(&cx->epu2apu_mb_lock); mutex_init(&cx->epu2cpu_mb_lock); - ret = cx18_create_out_workq(cx); - if (ret) - return ret; - ret = cx18_create_in_workq(cx); - if (ret) { - destroy_workqueue(cx->out_work_queue); + if (ret) return ret; - } cx18_init_in_work_orders(cx); @@ -1107,7 +1089,6 @@ free_mem: release_mem_region(cx->base_addr, CX18_MEM_SIZE); free_workqueues: destroy_workqueue(cx->in_work_queue); - destroy_workqueue(cx->out_work_queue); err: if (retval == 0) retval = -ENODEV; @@ -1259,7 +1240,6 @@ static void cx18_remove(struct pci_dev *pci_dev) cx18_halt_firmware(cx); destroy_workqueue(cx->in_work_queue); - destroy_workqueue(cx->out_work_queue); cx18_streams_cleanup(cx, 1); diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index f6f3e50..306caac 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -617,9 +617,6 @@ struct cx18 { struct cx18_in_work_order in_work_order[CX18_MAX_IN_WORK_ORDERS]; char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ - struct workqueue_struct *out_work_queue; - char out_workq_name[12]; /* "cx18-NN-out" */ - /* i2c */ struct i2c_adapter i2c_adap[2]; struct i2c_algo_bit_data i2c_algo[2]; diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h index 51765eb..713b0e6 100644 --- a/drivers/media/video/cx18/cx18-streams.h +++ b/drivers/media/video/cx18/cx18-streams.h @@ -42,8 +42,7 @@ static inline bool cx18_stream_enabled(struct cx18_stream *s) /* Related to submission of mdls to firmware */ static inline void cx18_stream_load_fw_queue(struct cx18_stream *s) { - struct cx18 *cx = s->cx; - queue_work(cx->out_work_queue, &s->out_work_order); + schedule_work(&s->out_work_order); } static inline void cx18_stream_put_mdl_fw(struct cx18_stream *s, diff --git a/drivers/media/video/cx231xx/cx231xx-dvb.c b/drivers/media/video/cx231xx/cx231xx-dvb.c index fe59a1c..363aa60 100644 --- a/drivers/media/video/cx231xx/cx231xx-dvb.c +++ b/drivers/media/video/cx231xx/cx231xx-dvb.c @@ -28,7 +28,6 @@ #include <media/videobuf-vmalloc.h> #include "xc5000.h" -#include "dvb_dummy_fe.h" #include "s5h1432.h" #include "tda18271.h" #include "s5h1411.h" @@ -619,7 +618,7 @@ static int dvb_init(struct cx231xx *dev) if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME - ": Failed to attach dummy front end\n"); + ": Failed to attach s5h1411 front end\n"); result = -EINVAL; goto out_free; } @@ -665,7 +664,7 @@ static int dvb_init(struct cx231xx *dev) if (dev->dvb->frontend == NULL) { printk(DRIVER_NAME - ": Failed to attach dummy front end\n"); + ": Failed to attach s5h1411 front end\n"); result = -EINVAL; goto out_free; } diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index f164618..6fc09dd 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1682,20 +1682,6 @@ static int cx25840_log_status(struct v4l2_subdev *sd) return 0; } -static int cx25840_s_config(struct v4l2_subdev *sd, int irq, void *platform_data) -{ - struct cx25840_state *state = to_state(sd); - struct i2c_client *client = v4l2_get_subdevdata(sd); - - if (platform_data) { - struct cx25840_platform_data *pdata = platform_data; - - state->pvr150_workaround = pdata->pvr150_workaround; - set_input(client, state->vid_input, state->aud_input); - } - return 0; -} - static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status, bool *handled) { @@ -1787,7 +1773,6 @@ static const struct v4l2_ctrl_ops cx25840_ctrl_ops = { static const struct v4l2_subdev_core_ops cx25840_core_ops = { .log_status = cx25840_log_status, - .s_config = cx25840_s_config, .g_chip_ident = cx25840_g_chip_ident, .g_ctrl = v4l2_subdev_g_ctrl, .s_ctrl = v4l2_subdev_s_ctrl, @@ -1974,7 +1959,6 @@ static int cx25840_probe(struct i2c_client *client, state->vid_input = CX25840_COMPOSITE7; state->aud_input = CX25840_AUDIO8; state->audclk_freq = 48000; - state->pvr150_workaround = 0; state->audmode = V4L2_TUNER_MODE_LANG1; state->vbi_line_offset = 8; state->id = id; @@ -2034,6 +2018,12 @@ static int cx25840_probe(struct i2c_client *client, v4l2_ctrl_cluster(2, &state->volume); v4l2_ctrl_handler_setup(&state->hdl); + if (client->dev.platform_data) { + struct cx25840_platform_data *pdata = client->dev.platform_data; + + state->pvr150_workaround = pdata->pvr150_workaround; + } + cx25840_ir_probe(sd); return 0; } diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c index 1f532e3..9f3bfc1 100644 --- a/drivers/media/video/davinci/vpif.c +++ b/drivers/media/video/davinci/vpif.c @@ -41,6 +41,183 @@ spinlock_t vpif_lock; void __iomem *vpif_base; +/** + * ch_params: video standard configuration parameters for vpif + * The table must include all presets from supported subdevices. + */ +const struct vpif_channel_config_params ch_params[] = { + /* HDTV formats */ + { + .name = "480p59_94", + .width = 720, + .height = 480, + .frm_fmt = 1, + .ycmux_mode = 0, + .eav2sav = 138-8, + .sav2eav = 720, + .l1 = 1, + .l3 = 43, + .l5 = 523, + .vsize = 525, + .capture_format = 0, + .vbi_supported = 0, + .hd_sd = 1, + .dv_preset = V4L2_DV_480P59_94, + }, + { + .name = "576p50", + .width = 720, + .height = 576, + .frm_fmt = 1, + .ycmux_mode = 0, + .eav2sav = 144-8, + .sav2eav = 720, + .l1 = 1, + .l3 = 45, + .l5 = 621, + .vsize = 625, + .capture_format = 0, + .vbi_supported = 0, + .hd_sd = 1, + .dv_preset = V4L2_DV_576P50, + }, + { + .name = "720p50", + .width = 1280, + .height = 720, + .frm_fmt = 1, + .ycmux_mode = 0, + .eav2sav = 700-8, + .sav2eav = 1280, + .l1 = 1, + .l3 = 26, + .l5 = 746, + .vsize = 750, + .capture_format = 0, + .vbi_supported = 0, + .hd_sd = 1, + .dv_preset = V4L2_DV_720P50, + }, + { + .name = "720p60", + .width = 1280, + .height = 720, + .frm_fmt = 1, + .ycmux_mode = 0, + .eav2sav = 370 - 8, + .sav2eav = 1280, + .l1 = 1, + .l3 = 26, + .l5 = 746, + .vsize = 750, + .capture_format = 0, + .vbi_supported = 0, + .hd_sd = 1, + .dv_preset = V4L2_DV_720P60, + }, + { + .name = "1080I50", + .width = 1920, + .height = 1080, + .frm_fmt = 0, + .ycmux_mode = 0, + .eav2sav = 720 - 8, + .sav2eav = 1920, + .l1 = 1, + .l3 = 21, + .l5 = 561, + .l7 = 563, + .l9 = 584, + .l11 = 1124, + .vsize = 1125, + .capture_format = 0, + .vbi_supported = 0, + .hd_sd = 1, + .dv_preset = V4L2_DV_1080I50, + }, + { + .name = "1080I60", + .width = 1920, + .height = 1080, + .frm_fmt = 0, + .ycmux_mode = 0, + .eav2sav = 280 - 8, + .sav2eav = 1920, + .l1 = 1, + .l3 = 21, + .l5 = 561, + .l7 = 563, + .l9 = 584, + .l11 = 1124, + .vsize = 1125, + .capture_format = 0, + .vbi_supported = 0, + .hd_sd = 1, + .dv_preset = V4L2_DV_1080I60, + }, + { + .name = "1080p60", + .width = 1920, + .height = 1080, + .frm_fmt = 1, + .ycmux_mode = 0, + .eav2sav = 280 - 8, + .sav2eav = 1920, + .l1 = 1, + .l3 = 42, + .l5 = 1122, + .vsize = 1125, + .capture_format = 0, + .vbi_supported = 0, + .hd_sd = 1, + .dv_preset = V4L2_DV_1080P60, + }, + + /* SDTV formats */ + { + .name = "NTSC_M", + .width = 720, + .height = 480, + .frm_fmt = 0, + .ycmux_mode = 1, + .eav2sav = 268, + .sav2eav = 1440, + .l1 = 1, + .l3 = 23, + .l5 = 263, + .l7 = 266, + .l9 = 286, + .l11 = 525, + .vsize = 525, + .capture_format = 0, + .vbi_supported = 1, + .hd_sd = 0, + .stdid = V4L2_STD_525_60, + }, + { + .name = "PAL_BDGHIK", + .width = 720, + .height = 576, + .frm_fmt = 0, + .ycmux_mode = 1, + .eav2sav = 280, + .sav2eav = 1440, + .l1 = 1, + .l3 = 23, + .l5 = 311, + .l7 = 313, + .l9 = 336, + .l11 = 624, + .vsize = 625, + .capture_format = 0, + .vbi_supported = 1, + .hd_sd = 0, + .stdid = V4L2_STD_625_50, + }, +}; + +const unsigned int vpif_ch_params_count = ARRAY_SIZE(ch_params); + static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val) { if (val) diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h index ebd5c43..10550bd 100644 --- a/drivers/media/video/davinci/vpif.h +++ b/drivers/media/video/davinci/vpif.h @@ -577,12 +577,10 @@ struct vpif_channel_config_params { char name[VPIF_MAX_NAME]; /* Name of the mode */ u16 width; /* Indicates width of the image */ u16 height; /* Indicates height of the image */ - u8 fps; - u8 frm_fmt; /* Indicates whether this is interlaced - * or progressive format */ - u8 ycmux_mode; /* Indicates whether this mode requires - * single or two channels */ - u16 eav2sav; /* length of sav 2 eav */ + u8 frm_fmt; /* Interlaced (0) or progressive (1) */ + u8 ycmux_mode; /* This mode requires one (0) or two (1) + channels */ + u16 eav2sav; /* length of eav 2 sav */ u16 sav2eav; /* length of sav 2 eav */ u16 l1, l3, l5, l7, l9, l11; /* Other parameter configurations */ u16 vsize; /* Vertical size of the image */ @@ -590,10 +588,14 @@ struct vpif_channel_config_params { * is in BT or in CCD/CMOS */ u8 vbi_supported; /* Indicates whether this mode * supports capturing vbi or not */ - u8 hd_sd; - v4l2_std_id stdid; + u8 hd_sd; /* HDTV (1) or SDTV (0) format */ + v4l2_std_id stdid; /* SDTV format */ + u32 dv_preset; /* HDTV format */ }; +extern const unsigned int vpif_ch_params_count; +extern const struct vpif_channel_config_params ch_params[]; + struct vpif_video_params; struct vpif_params; struct vpif_vbi_params; diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c index 193abab..d93ad74 100644 --- a/drivers/media/video/davinci/vpif_capture.c +++ b/drivers/media/video/davinci/vpif_capture.c @@ -37,6 +37,7 @@ #include <linux/slab.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-chip-ident.h> #include "vpif_capture.h" #include "vpif.h" @@ -81,20 +82,6 @@ static struct vpif_device vpif_obj = { {NULL} }; static struct device *vpif_dev; /** - * ch_params: video standard configuration parameters for vpif - */ -static const struct vpif_channel_config_params ch_params[] = { - { - "NTSC_M", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266, - 286, 525, 525, 0, 1, 0, V4L2_STD_525_60, - }, - { - "PAL_BDGHIK", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313, - 336, 624, 625, 0, 1, 0, V4L2_STD_625_50, - }, -}; - -/** * vpif_uservirt_to_phys : translate user/virtual address to phy address * @virtp: user/virtual address * @@ -342,7 +329,7 @@ static void vpif_schedule_next_buffer(struct common_obj *common) * @dev_id: dev_id ptr * * It changes status of the captured buffer, takes next buffer from the queue - * and sets its address in VPIF registers + * and sets its address in VPIF registers */ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) { @@ -435,24 +422,31 @@ static int vpif_update_std_info(struct channel_obj *ch) struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; struct vpif_params *vpifparams = &ch->vpifparams; const struct vpif_channel_config_params *config; - struct vpif_channel_config_params *std_info; + struct vpif_channel_config_params *std_info = &vpifparams->std_info; struct video_obj *vid_ch = &ch->video; int index; vpif_dbg(2, debug, "vpif_update_std_info\n"); - std_info = &vpifparams->std_info; - - for (index = 0; index < ARRAY_SIZE(ch_params); index++) { + for (index = 0; index < vpif_ch_params_count; index++) { config = &ch_params[index]; - if (config->stdid & vid_ch->stdid) { - memcpy(std_info, config, sizeof(*config)); - break; + if (config->hd_sd == 0) { + vpif_dbg(2, debug, "SD format\n"); + if (config->stdid & vid_ch->stdid) { + memcpy(std_info, config, sizeof(*config)); + break; + } + } else { + vpif_dbg(2, debug, "HD format\n"); + if (config->dv_preset == vid_ch->dv_preset) { + memcpy(std_info, config, sizeof(*config)); + break; + } } } /* standard not found */ - if (index == ARRAY_SIZE(ch_params)) + if (index == vpif_ch_params_count) return -EINVAL; common->fmt.fmt.pix.width = std_info->width; @@ -462,6 +456,7 @@ static int vpif_update_std_info(struct channel_obj *ch) common->fmt.fmt.pix.bytesperline = std_info->width; vpifparams->video_params.hpitch = std_info->width; vpifparams->video_params.storage_mode = std_info->frm_fmt; + return 0; } @@ -757,7 +752,7 @@ static int vpif_open(struct file *filep) struct video_obj *vid_ch; struct channel_obj *ch; struct vpif_fh *fh; - int i, ret = 0; + int i; vpif_dbg(2, debug, "vpif_open\n"); @@ -766,9 +761,6 @@ static int vpif_open(struct file *filep) vid_ch = &ch->video; common = &ch->common[VPIF_VIDEO_INDEX]; - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - if (NULL == ch->curr_subdev_info) { /** * search through the sub device to see a registered @@ -785,8 +777,7 @@ static int vpif_open(struct file *filep) } if (i == config->subdev_count) { vpif_err("No sub device registered\n"); - ret = -ENOENT; - goto exit; + return -ENOENT; } } @@ -794,8 +785,7 @@ static int vpif_open(struct file *filep) fh = kzalloc(sizeof(struct vpif_fh), GFP_KERNEL); if (NULL == fh) { vpif_err("unable to allocate memory for file handle object\n"); - ret = -ENOMEM; - goto exit; + return -ENOMEM; } /* store pointer to fh in private_data member of filep */ @@ -815,9 +805,7 @@ static int vpif_open(struct file *filep) /* Initialize priority of this instance to default priority */ fh->prio = V4L2_PRIORITY_UNSET; v4l2_prio_open(&ch->prio, &fh->prio); -exit: - mutex_unlock(&common->lock); - return ret; + return 0; } /** @@ -837,9 +825,6 @@ static int vpif_release(struct file *filep) common = &ch->common[VPIF_VIDEO_INDEX]; - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - /* if this instance is doing IO */ if (fh->io_allowed[VPIF_VIDEO_INDEX]) { /* Reset io_usrs member of channel object */ @@ -863,9 +848,6 @@ static int vpif_release(struct file *filep) /* Decrement channel usrs counter */ ch->usrs--; - /* unlock mutex on channel object */ - mutex_unlock(&common->lock); - /* Close the priority */ v4l2_prio_close(&ch->prio, fh->prio); @@ -890,7 +872,6 @@ static int vpif_reqbufs(struct file *file, void *priv, struct channel_obj *ch = fh->channel; struct common_obj *common; u8 index = 0; - int ret = 0; vpif_dbg(2, debug, "vpif_reqbufs\n"); @@ -913,13 +894,8 @@ static int vpif_reqbufs(struct file *file, void *priv, common = &ch->common[index]; - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - - if (0 != common->io_usrs) { - ret = -EBUSY; - goto reqbuf_exit; - } + if (0 != common->io_usrs) + return -EBUSY; /* Initialize videobuf queue as per the buffer type */ videobuf_queue_dma_contig_init(&common->buffer_queue, @@ -928,7 +904,7 @@ static int vpif_reqbufs(struct file *file, void *priv, reqbuf->type, common->fmt.fmt.pix.field, sizeof(struct videobuf_buffer), fh, - NULL); + &common->lock); /* Set io allowed member of file handle to TRUE */ fh->io_allowed[index] = 1; @@ -939,11 +915,7 @@ static int vpif_reqbufs(struct file *file, void *priv, INIT_LIST_HEAD(&common->dma_queue); /* Allocate buffers */ - ret = videobuf_reqbufs(&common->buffer_queue, reqbuf); - -reqbuf_exit: - mutex_unlock(&common->lock); - return ret; + return videobuf_reqbufs(&common->buffer_queue, reqbuf); } /** @@ -1157,11 +1129,6 @@ static int vpif_streamon(struct file *file, void *priv, return ret; } - if (mutex_lock_interruptible(&common->lock)) { - ret = -ERESTARTSYS; - goto streamoff_exit; - } - /* If buffer queue is empty, return error */ if (list_empty(&common->dma_queue)) { vpif_dbg(1, debug, "buffer queue is empty\n"); @@ -1240,13 +1207,10 @@ static int vpif_streamon(struct file *file, void *priv, enable_channel1(1); } channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1; - mutex_unlock(&common->lock); return ret; exit: - mutex_unlock(&common->lock); -streamoff_exit: - ret = videobuf_streamoff(&common->buffer_queue); + videobuf_streamoff(&common->buffer_queue); return ret; } @@ -1284,9 +1248,6 @@ static int vpif_streamoff(struct file *file, void *priv, return -EINVAL; } - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - /* disable channel */ if (VPIF_CHANNEL0_VIDEO == ch->channel_id) { enable_channel0(0); @@ -1304,8 +1265,6 @@ static int vpif_streamoff(struct file *file, void *priv, if (ret && (ret != -ENOIOCTLCMD)) vpif_dbg(1, debug, "stream off failed in subdev\n"); - mutex_unlock(&common->lock); - return videobuf_streamoff(&common->buffer_queue); } @@ -1381,21 +1340,16 @@ static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id) { struct vpif_fh *fh = priv; struct channel_obj *ch = fh->channel; - struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; int ret = 0; vpif_dbg(2, debug, "vpif_querystd\n"); - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - /* Call querystd function of decoder device */ ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video, querystd, std_id); if (ret < 0) vpif_dbg(1, debug, "Failed to set standard for sub devices\n"); - mutex_unlock(&common->lock); return ret; } @@ -1451,16 +1405,14 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id) fh->initialized = 1; /* Call encoder subdevice function to set the standard */ - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - ch->video.stdid = *std_id; + ch->video.dv_preset = V4L2_DV_INVALID; + memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings)); /* Get the information about the standard */ if (vpif_update_std_info(ch)) { - ret = -EINVAL; vpif_err("Error getting the standard info\n"); - goto s_std_exit; + return -EINVAL; } /* Configure the default format information */ @@ -1471,9 +1423,6 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id) s_std, *std_id); if (ret < 0) vpif_dbg(1, debug, "Failed to set standard for sub devices\n"); - -s_std_exit: - mutex_unlock(&common->lock); return ret; } @@ -1567,9 +1516,6 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index) return -EINVAL; } - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - /* first setup input path from sub device to vpif */ if (config->setup_input_path) { ret = config->setup_input_path(ch->channel_id, @@ -1578,7 +1524,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index) vpif_dbg(1, debug, "couldn't setup input path for the" " sub device %s, for input index %d\n", subdev_info->name, index); - goto exit; + return ret; } } @@ -1589,7 +1535,7 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index) input, output, 0); if (ret < 0) { vpif_dbg(1, debug, "Failed to set input\n"); - goto exit; + return ret; } } vid_ch->input_idx = index; @@ -1600,9 +1546,6 @@ static int vpif_s_input(struct file *file, void *priv, unsigned int index) /* update tvnorms from the sub device input info */ ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std; - -exit: - mutex_unlock(&common->lock); return ret; } @@ -1671,11 +1614,7 @@ static int vpif_g_fmt_vid_cap(struct file *file, void *priv, return -EINVAL; /* Fill in the information about format */ - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - *fmt = common->fmt; - mutex_unlock(&common->lock); return 0; } @@ -1694,7 +1633,7 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_pix_format *pixfmt; int ret = 0; - vpif_dbg(2, debug, "VIDIOC_S_FMT\n"); + vpif_dbg(2, debug, "%s\n", __func__); /* If streaming is started, return error */ if (common->started) { @@ -1723,12 +1662,7 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv, if (ret) return ret; /* store the format in the channel object */ - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - common->fmt = *fmt; - mutex_unlock(&common->lock); - return 0; } @@ -1807,6 +1741,306 @@ static int vpif_cropcap(struct file *file, void *priv, return 0; } +/** + * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler + * @file: file ptr + * @priv: file handle + * @preset: input preset + */ +static int vpif_enum_dv_presets(struct file *file, void *priv, + struct v4l2_dv_enum_preset *preset) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + + return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], + video, enum_dv_presets, preset); +} + +/** + * vpif_query_dv_presets() - QUERY_DV_PRESET handler + * @file: file ptr + * @priv: file handle + * @preset: input preset + */ +static int vpif_query_dv_preset(struct file *file, void *priv, + struct v4l2_dv_preset *preset) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + + return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], + video, query_dv_preset, preset); +} +/** + * vpif_s_dv_presets() - S_DV_PRESETS handler + * @file: file ptr + * @priv: file handle + * @preset: input preset + */ +static int vpif_s_dv_preset(struct file *file, void *priv, + struct v4l2_dv_preset *preset) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; + int ret = 0; + + if (common->started) { + vpif_dbg(1, debug, "streaming in progress\n"); + return -EBUSY; + } + + if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) || + (VPIF_CHANNEL1_VIDEO == ch->channel_id)) { + if (!fh->initialized) { + vpif_dbg(1, debug, "Channel Busy\n"); + return -EBUSY; + } + } + + ret = v4l2_prio_check(&ch->prio, fh->prio); + if (ret) + return ret; + + fh->initialized = 1; + + /* Call encoder subdevice function to set the standard */ + if (mutex_lock_interruptible(&common->lock)) + return -ERESTARTSYS; + + ch->video.dv_preset = preset->preset; + ch->video.stdid = V4L2_STD_UNKNOWN; + memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings)); + + /* Get the information about the standard */ + if (vpif_update_std_info(ch)) { + vpif_dbg(1, debug, "Error getting the standard info\n"); + ret = -EINVAL; + } else { + /* Configure the default format information */ + vpif_config_format(ch); + + ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], + video, s_dv_preset, preset); + } + + mutex_unlock(&common->lock); + + return ret; +} +/** + * vpif_g_dv_presets() - G_DV_PRESETS handler + * @file: file ptr + * @priv: file handle + * @preset: input preset + */ +static int vpif_g_dv_preset(struct file *file, void *priv, + struct v4l2_dv_preset *preset) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + + preset->preset = ch->video.dv_preset; + + return 0; +} + +/** + * vpif_s_dv_timings() - S_DV_TIMINGS handler + * @file: file ptr + * @priv: file handle + * @timings: digital video timings + */ +static int vpif_s_dv_timings(struct file *file, void *priv, + struct v4l2_dv_timings *timings) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct vpif_params *vpifparams = &ch->vpifparams; + struct vpif_channel_config_params *std_info = &vpifparams->std_info; + struct video_obj *vid_ch = &ch->video; + struct v4l2_bt_timings *bt = &vid_ch->bt_timings; + int ret; + + if (timings->type != V4L2_DV_BT_656_1120) { + vpif_dbg(2, debug, "Timing type not defined\n"); + return -EINVAL; + } + + /* Configure subdevice timings, if any */ + ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], + video, s_dv_timings, timings); + if (ret == -ENOIOCTLCMD) { + vpif_dbg(2, debug, "Custom DV timings not supported by " + "subdevice\n"); + return -EINVAL; + } + if (ret < 0) { + vpif_dbg(2, debug, "Error setting custom DV timings\n"); + return ret; + } + + if (!(timings->bt.width && timings->bt.height && + (timings->bt.hbackporch || + timings->bt.hfrontporch || + timings->bt.hsync) && + timings->bt.vfrontporch && + (timings->bt.vbackporch || + timings->bt.vsync))) { + vpif_dbg(2, debug, "Timings for width, height, " + "horizontal back porch, horizontal sync, " + "horizontal front porch, vertical back porch, " + "vertical sync and vertical back porch " + "must be defined\n"); + return -EINVAL; + } + + *bt = timings->bt; + + /* Configure video port timings */ + + std_info->eav2sav = bt->hbackporch + bt->hfrontporch + + bt->hsync - 8; + std_info->sav2eav = bt->width; + + std_info->l1 = 1; + std_info->l3 = bt->vsync + bt->vbackporch + 1; + + if (bt->interlaced) { + if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) { + std_info->vsize = bt->height * 2 + + bt->vfrontporch + bt->vsync + bt->vbackporch + + bt->il_vfrontporch + bt->il_vsync + + bt->il_vbackporch; + std_info->l5 = std_info->vsize/2 - + (bt->vfrontporch - 1); + std_info->l7 = std_info->vsize/2 + 1; + std_info->l9 = std_info->l7 + bt->il_vsync + + bt->il_vbackporch + 1; + std_info->l11 = std_info->vsize - + (bt->il_vfrontporch - 1); + } else { + vpif_dbg(2, debug, "Required timing values for " + "interlaced BT format missing\n"); + return -EINVAL; + } + } else { + std_info->vsize = bt->height + bt->vfrontporch + + bt->vsync + bt->vbackporch; + std_info->l5 = std_info->vsize - (bt->vfrontporch - 1); + } + strncpy(std_info->name, "Custom timings BT656/1120", VPIF_MAX_NAME); + std_info->width = bt->width; + std_info->height = bt->height; + std_info->frm_fmt = bt->interlaced ? 0 : 1; + std_info->ycmux_mode = 0; + std_info->capture_format = 0; + std_info->vbi_supported = 0; + std_info->hd_sd = 1; + std_info->stdid = 0; + std_info->dv_preset = V4L2_DV_INVALID; + + vid_ch->stdid = 0; + vid_ch->dv_preset = V4L2_DV_INVALID; + return 0; +} + +/** + * vpif_g_dv_timings() - G_DV_TIMINGS handler + * @file: file ptr + * @priv: file handle + * @timings: digital video timings + */ +static int vpif_g_dv_timings(struct file *file, void *priv, + struct v4l2_dv_timings *timings) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct video_obj *vid_ch = &ch->video; + struct v4l2_bt_timings *bt = &vid_ch->bt_timings; + + timings->bt = *bt; + + return 0; +} + +/* + * vpif_g_chip_ident() - Identify the chip + * @file: file ptr + * @priv: file handle + * @chip: chip identity + * + * Returns zero or -EINVAL if read operations fails. + */ +static int vpif_g_chip_ident(struct file *file, void *priv, + struct v4l2_dbg_chip_ident *chip) +{ + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && + chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) { + vpif_dbg(2, debug, "match_type is invalid.\n"); + return -EINVAL; + } + + return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core, + g_chip_ident, chip); +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +/* + * vpif_dbg_g_register() - Read register + * @file: file ptr + * @priv: file handle + * @reg: register to be read + * + * Debugging only + * Returns zero or -EINVAL if read operations fails. + */ +static int vpif_dbg_g_register(struct file *file, void *priv, + struct v4l2_dbg_register *reg){ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + + return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core, + g_register, reg); +} + +/* + * vpif_dbg_s_register() - Write to register + * @file: file ptr + * @priv: file handle + * @reg: register to be modified + * + * Debugging only + * Returns zero or -EINVAL if write operations fails. + */ +static int vpif_dbg_s_register(struct file *file, void *priv, + struct v4l2_dbg_register *reg){ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + + return v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core, + s_register, reg); +} +#endif + +/* + * vpif_log_status() - Status information + * @file: file ptr + * @priv: file handle + * + * Returns zero. + */ +static int vpif_log_status(struct file *filep, void *priv) +{ + /* status for sub devices */ + v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status); + + return 0; +} + /* vpif capture ioctl operations */ static const struct v4l2_ioctl_ops vpif_ioctl_ops = { .vidioc_querycap = vpif_querycap, @@ -1829,6 +2063,18 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = { .vidioc_streamon = vpif_streamon, .vidioc_streamoff = vpif_streamoff, .vidioc_cropcap = vpif_cropcap, + .vidioc_enum_dv_presets = vpif_enum_dv_presets, + .vidioc_s_dv_preset = vpif_s_dv_preset, + .vidioc_g_dv_preset = vpif_g_dv_preset, + .vidioc_query_dv_preset = vpif_query_dv_preset, + .vidioc_s_dv_timings = vpif_s_dv_timings, + .vidioc_g_dv_timings = vpif_g_dv_timings, + .vidioc_g_chip_ident = vpif_g_chip_ident, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vpif_dbg_g_register, + .vidioc_s_register = vpif_dbg_s_register, +#endif + .vidioc_log_status = vpif_log_status, }; /* vpif file operations */ @@ -1836,7 +2082,7 @@ static struct v4l2_file_operations vpif_fops = { .owner = THIS_MODULE, .open = vpif_open, .release = vpif_release, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, .mmap = vpif_mmap, .poll = vpif_poll }; @@ -1979,6 +2225,7 @@ static __init int vpif_probe(struct platform_device *pdev) common = &(ch->common[VPIF_VIDEO_INDEX]); spin_lock_init(&common->irqlock); mutex_init(&common->lock); + ch->video_dev->lock = &common->lock; /* Initialize prio member of channel object */ v4l2_prio_init(&ch->prio); err = video_register_device(ch->video_dev, @@ -2026,9 +2273,9 @@ static __init int vpif_probe(struct platform_device *pdev) if (vpif_obj.sd[i]) vpif_obj.sd[i]->grp_id = 1 << i; } - v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver" - " initialized\n"); + v4l2_info(&vpif_obj.v4l2_dev, + "DM646x VPIF capture driver initialized\n"); return 0; probe_subdev_out: diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h index 4e12ec8..7a4196d 100644 --- a/drivers/media/video/davinci/vpif_capture.h +++ b/drivers/media/video/davinci/vpif_capture.h @@ -59,6 +59,8 @@ struct video_obj { enum v4l2_field buf_field; /* Currently selected or default standard */ v4l2_std_id stdid; + u32 dv_preset; + struct v4l2_bt_timings bt_timings; /* This is to track the last input that is passed to application */ u32 input_idx; }; diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index 412c65d..cdf659a 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c @@ -38,6 +38,7 @@ #include <media/adv7343.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-chip-ident.h> #include <mach/dm646x.h> @@ -84,17 +85,6 @@ static struct vpif_config_params config_params = { static struct vpif_device vpif_obj = { {NULL} }; static struct device *vpif_dev; -static const struct vpif_channel_config_params ch_params[] = { - { - "NTSC", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266, - 286, 525, 525, 0, 1, 0, V4L2_STD_525_60, - }, - { - "PAL", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313, - 336, 624, 625, 0, 1, 0, V4L2_STD_625_50, - }, -}; - /* * vpif_uservirt_to_phys: This function is used to convert user * space virtual address to physical address. @@ -373,30 +363,54 @@ static irqreturn_t vpif_channel_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static int vpif_get_std_info(struct channel_obj *ch) +static int vpif_update_std_info(struct channel_obj *ch) { - struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; struct video_obj *vid_ch = &ch->video; struct vpif_params *vpifparams = &ch->vpifparams; struct vpif_channel_config_params *std_info = &vpifparams->std_info; const struct vpif_channel_config_params *config; - int index; - - std_info->stdid = vid_ch->stdid; - if (!std_info->stdid) - return -1; + int i; - for (index = 0; index < ARRAY_SIZE(ch_params); index++) { - config = &ch_params[index]; - if (config->stdid & std_info->stdid) { - memcpy(std_info, config, sizeof(*config)); - break; + for (i = 0; i < vpif_ch_params_count; i++) { + config = &ch_params[i]; + if (config->hd_sd == 0) { + vpif_dbg(2, debug, "SD format\n"); + if (config->stdid & vid_ch->stdid) { + memcpy(std_info, config, sizeof(*config)); + break; + } + } else { + vpif_dbg(2, debug, "HD format\n"); + if (config->dv_preset == vid_ch->dv_preset) { + memcpy(std_info, config, sizeof(*config)); + break; + } } } - if (index == ARRAY_SIZE(ch_params)) - return -1; + if (i == vpif_ch_params_count) { + vpif_dbg(1, debug, "Format not found\n"); + return -EINVAL; + } + + return 0; +} + +static int vpif_update_resolution(struct channel_obj *ch) +{ + struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; + struct video_obj *vid_ch = &ch->video; + struct vpif_params *vpifparams = &ch->vpifparams; + struct vpif_channel_config_params *std_info = &vpifparams->std_info; + + if (!vid_ch->stdid && !vid_ch->dv_preset && !vid_ch->bt_timings.height) + return -EINVAL; + + if (vid_ch->stdid || vid_ch->dv_preset) { + if (vpif_update_std_info(ch)) + return -EINVAL; + } common->fmt.fmt.pix.width = std_info->width; common->fmt.fmt.pix.height = std_info->height; @@ -404,8 +418,8 @@ static int vpif_get_std_info(struct channel_obj *ch) common->fmt.fmt.pix.width, common->fmt.fmt.pix.height); /* Set height and width paramateres */ - ch->common[VPIF_VIDEO_INDEX].height = std_info->height; - ch->common[VPIF_VIDEO_INDEX].width = std_info->width; + common->height = std_info->height; + common->width = std_info->width; return 0; } @@ -516,10 +530,8 @@ static int vpif_check_format(struct channel_obj *ch, else sizeimage = config_params.channel_bufsize[ch->channel_id]; - if (vpif_get_std_info(ch)) { - vpif_err("Error getting the standard info\n"); + if (vpif_update_resolution(ch)) return -EINVAL; - } hpitch = pixfmt->bytesperline; vpitch = sizeimage / (hpitch * 2); @@ -568,7 +580,10 @@ static void vpif_config_addr(struct channel_obj *ch, int muxmode) static int vpif_mmap(struct file *filep, struct vm_area_struct *vma) { struct vpif_fh *fh = filep->private_data; - struct common_obj *common = &fh->channel->common[VPIF_VIDEO_INDEX]; + struct channel_obj *ch = fh->channel; + struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]); + + vpif_dbg(2, debug, "vpif_mmap\n"); return videobuf_mmap_mapper(&common->buffer_queue, vma); } @@ -637,9 +652,6 @@ static int vpif_release(struct file *filep) struct channel_obj *ch = fh->channel; struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - /* if this instance is doing IO */ if (fh->io_allowed[VPIF_VIDEO_INDEX]) { /* Reset io_usrs member of channel object */ @@ -662,8 +674,6 @@ static int vpif_release(struct file *filep) config_params.numbuffers[ch->channel_id]; } - mutex_unlock(&common->lock); - /* Decrement channel usrs counter */ atomic_dec(&ch->usrs); /* If this file handle has initialize encoder device, reset it */ @@ -680,7 +690,12 @@ static int vpif_release(struct file *filep) } /* functions implementing ioctls */ - +/** + * vpif_querycap() - QUERYCAP handler + * @file: file ptr + * @priv: file handle + * @cap: ptr to v4l2_capability structure + */ static int vpif_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -722,17 +737,9 @@ static int vpif_g_fmt_vid_out(struct file *file, void *priv, if (common->fmt.type != fmt->type) return -EINVAL; - /* Fill in the information about format */ - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - - if (vpif_get_std_info(ch)) { - vpif_err("Error getting the standard info\n"); + if (vpif_update_resolution(ch)) return -EINVAL; - } - *fmt = common->fmt; - mutex_unlock(&common->lock); return 0; } @@ -773,12 +780,7 @@ static int vpif_s_fmt_vid_out(struct file *file, void *priv, /* store the pix format in the channel object */ common->fmt.fmt.pix = *pixfmt; /* store the format in the channel object */ - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - common->fmt = *fmt; - mutex_unlock(&common->lock); - return 0; } @@ -808,7 +810,6 @@ static int vpif_reqbufs(struct file *file, void *priv, struct common_obj *common; enum v4l2_field field; u8 index = 0; - int ret = 0; /* This file handle has not initialized the channel, It is not allowed to do settings */ @@ -826,18 +827,12 @@ static int vpif_reqbufs(struct file *file, void *priv, index = VPIF_VIDEO_INDEX; common = &ch->common[index]; - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - if (common->fmt.type != reqbuf->type) { - ret = -EINVAL; - goto reqbuf_exit; - } + if (common->fmt.type != reqbuf->type) + return -EINVAL; - if (0 != common->io_usrs) { - ret = -EBUSY; - goto reqbuf_exit; - } + if (0 != common->io_usrs) + return -EBUSY; if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY) @@ -854,7 +849,7 @@ static int vpif_reqbufs(struct file *file, void *priv, &common->irqlock, reqbuf->type, field, sizeof(struct videobuf_buffer), fh, - NULL); + &common->lock); /* Set io allowed member of file handle to TRUE */ fh->io_allowed[index] = 1; @@ -865,11 +860,7 @@ static int vpif_reqbufs(struct file *file, void *priv, INIT_LIST_HEAD(&common->dma_queue); /* Allocate buffers */ - ret = videobuf_reqbufs(&common->buffer_queue, reqbuf); - -reqbuf_exit: - mutex_unlock(&common->lock); - return ret; + return videobuf_reqbufs(&common->buffer_queue, reqbuf); } static int vpif_querybuf(struct file *file, void *priv, @@ -990,22 +981,19 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id) } /* Call encoder subdevice function to set the standard */ - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - ch->video.stdid = *std_id; + ch->video.dv_preset = V4L2_DV_INVALID; + memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings)); + /* Get the information about the standard */ - if (vpif_get_std_info(ch)) { - vpif_err("Error getting the standard info\n"); + if (vpif_update_resolution(ch)) return -EINVAL; - } if ((ch->vpifparams.std_info.width * ch->vpifparams.std_info.height * 2) > config_params.channel_bufsize[ch->channel_id]) { vpif_err("invalid std for this size\n"); - ret = -EINVAL; - goto s_std_exit; + return -EINVAL; } common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width; @@ -1016,16 +1004,13 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id) s_std_output, *std_id); if (ret < 0) { vpif_err("Failed to set output standard\n"); - goto s_std_exit; + return ret; } ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core, s_std, *std_id); if (ret < 0) vpif_err("Failed to set standard for sub devices\n"); - -s_std_exit: - mutex_unlock(&common->lock); return ret; } @@ -1090,21 +1075,17 @@ static int vpif_streamon(struct file *file, void *priv, if (ret < 0) return ret; - /* Call videobuf_streamon to start streaming in videobuf */ + /* Call videobuf_streamon to start streaming in videobuf */ ret = videobuf_streamon(&common->buffer_queue); if (ret < 0) { vpif_err("videobuf_streamon\n"); return ret; } - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - /* If buffer queue is empty, return error */ if (list_empty(&common->dma_queue)) { vpif_err("buffer queue is empty\n"); - ret = -EIO; - goto streamon_exit; + return -EIO; } /* Get the next frame from the buffer queue */ @@ -1130,8 +1111,7 @@ static int vpif_streamon(struct file *file, void *priv, || (!ch->vpifparams.std_info.frm_fmt && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) { vpif_err("conflict in field format and std format\n"); - ret = -EINVAL; - goto streamon_exit; + return -EINVAL; } /* clock settings */ @@ -1140,13 +1120,13 @@ static int vpif_streamon(struct file *file, void *priv, ch->vpifparams.std_info.hd_sd); if (ret < 0) { vpif_err("can't set clock\n"); - goto streamon_exit; + return ret; } /* set the parameters and addresses */ ret = vpif_set_video_params(vpif, ch->channel_id + 2); if (ret < 0) - goto streamon_exit; + return ret; common->started = ret; vpif_config_addr(ch, ret); @@ -1171,9 +1151,6 @@ static int vpif_streamon(struct file *file, void *priv, } channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1; } - -streamon_exit: - mutex_unlock(&common->lock); return ret; } @@ -1199,9 +1176,6 @@ static int vpif_streamoff(struct file *file, void *priv, return -EINVAL; } - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) { /* disable channel */ if (VPIF_CHANNEL2_VIDEO == ch->channel_id) { @@ -1216,8 +1190,6 @@ static int vpif_streamoff(struct file *file, void *priv, } common->started = 0; - mutex_unlock(&common->lock); - return videobuf_streamoff(&common->buffer_queue); } @@ -1264,13 +1236,9 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i) struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; int ret = 0; - if (mutex_lock_interruptible(&common->lock)) - return -ERESTARTSYS; - if (common->started) { vpif_err("Streaming in progress\n"); - ret = -EBUSY; - goto s_output_exit; + return -EBUSY; } ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video, @@ -1280,9 +1248,6 @@ static int vpif_s_output(struct file *file, void *priv, unsigned int i) vpif_err("Failed to set output standard\n"); vid_ch->output_id = i; - -s_output_exit: - mutex_unlock(&common->lock); return ret; } @@ -1315,6 +1280,287 @@ static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p) return v4l2_prio_change(&ch->prio, &fh->prio, p); } +/** + * vpif_enum_dv_presets() - ENUM_DV_PRESETS handler + * @file: file ptr + * @priv: file handle + * @preset: input preset + */ +static int vpif_enum_dv_presets(struct file *file, void *priv, + struct v4l2_dv_enum_preset *preset) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct video_obj *vid_ch = &ch->video; + + return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], + video, enum_dv_presets, preset); +} + +/** + * vpif_s_dv_presets() - S_DV_PRESETS handler + * @file: file ptr + * @priv: file handle + * @preset: input preset + */ +static int vpif_s_dv_preset(struct file *file, void *priv, + struct v4l2_dv_preset *preset) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX]; + struct video_obj *vid_ch = &ch->video; + int ret = 0; + + if (common->started) { + vpif_dbg(1, debug, "streaming in progress\n"); + return -EBUSY; + } + + ret = v4l2_prio_check(&ch->prio, fh->prio); + if (ret != 0) + return ret; + + fh->initialized = 1; + + /* Call encoder subdevice function to set the standard */ + if (mutex_lock_interruptible(&common->lock)) + return -ERESTARTSYS; + + ch->video.dv_preset = preset->preset; + ch->video.stdid = V4L2_STD_UNKNOWN; + memset(&ch->video.bt_timings, 0, sizeof(ch->video.bt_timings)); + + /* Get the information about the standard */ + if (vpif_update_resolution(ch)) { + ret = -EINVAL; + } else { + /* Configure the default format information */ + vpif_config_format(ch); + + ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], + video, s_dv_preset, preset); + } + + mutex_unlock(&common->lock); + + return ret; +} +/** + * vpif_g_dv_presets() - G_DV_PRESETS handler + * @file: file ptr + * @priv: file handle + * @preset: input preset + */ +static int vpif_g_dv_preset(struct file *file, void *priv, + struct v4l2_dv_preset *preset) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + + preset->preset = ch->video.dv_preset; + + return 0; +} +/** + * vpif_s_dv_timings() - S_DV_TIMINGS handler + * @file: file ptr + * @priv: file handle + * @timings: digital video timings + */ +static int vpif_s_dv_timings(struct file *file, void *priv, + struct v4l2_dv_timings *timings) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct vpif_params *vpifparams = &ch->vpifparams; + struct vpif_channel_config_params *std_info = &vpifparams->std_info; + struct video_obj *vid_ch = &ch->video; + struct v4l2_bt_timings *bt = &vid_ch->bt_timings; + int ret; + + if (timings->type != V4L2_DV_BT_656_1120) { + vpif_dbg(2, debug, "Timing type not defined\n"); + return -EINVAL; + } + + /* Configure subdevice timings, if any */ + ret = v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], + video, s_dv_timings, timings); + if (ret == -ENOIOCTLCMD) { + vpif_dbg(2, debug, "Custom DV timings not supported by " + "subdevice\n"); + return -EINVAL; + } + if (ret < 0) { + vpif_dbg(2, debug, "Error setting custom DV timings\n"); + return ret; + } + + if (!(timings->bt.width && timings->bt.height && + (timings->bt.hbackporch || + timings->bt.hfrontporch || + timings->bt.hsync) && + timings->bt.vfrontporch && + (timings->bt.vbackporch || + timings->bt.vsync))) { + vpif_dbg(2, debug, "Timings for width, height, " + "horizontal back porch, horizontal sync, " + "horizontal front porch, vertical back porch, " + "vertical sync and vertical back porch " + "must be defined\n"); + return -EINVAL; + } + + *bt = timings->bt; + + /* Configure video port timings */ + + std_info->eav2sav = bt->hbackporch + bt->hfrontporch + + bt->hsync - 8; + std_info->sav2eav = bt->width; + + std_info->l1 = 1; + std_info->l3 = bt->vsync + bt->vbackporch + 1; + + if (bt->interlaced) { + if (bt->il_vbackporch || bt->il_vfrontporch || bt->il_vsync) { + std_info->vsize = bt->height * 2 + + bt->vfrontporch + bt->vsync + bt->vbackporch + + bt->il_vfrontporch + bt->il_vsync + + bt->il_vbackporch; + std_info->l5 = std_info->vsize/2 - + (bt->vfrontporch - 1); + std_info->l7 = std_info->vsize/2 + 1; + std_info->l9 = std_info->l7 + bt->il_vsync + + bt->il_vbackporch + 1; + std_info->l11 = std_info->vsize - + (bt->il_vfrontporch - 1); + } else { + vpif_dbg(2, debug, "Required timing values for " + "interlaced BT format missing\n"); + return -EINVAL; + } + } else { + std_info->vsize = bt->height + bt->vfrontporch + + bt->vsync + bt->vbackporch; + std_info->l5 = std_info->vsize - (bt->vfrontporch - 1); + } + strncpy(std_info->name, "Custom timings BT656/1120", + VPIF_MAX_NAME); + std_info->width = bt->width; + std_info->height = bt->height; + std_info->frm_fmt = bt->interlaced ? 0 : 1; + std_info->ycmux_mode = 0; + std_info->capture_format = 0; + std_info->vbi_supported = 0; + std_info->hd_sd = 1; + std_info->stdid = 0; + std_info->dv_preset = V4L2_DV_INVALID; + + vid_ch->stdid = 0; + vid_ch->dv_preset = V4L2_DV_INVALID; + + return 0; +} + +/** + * vpif_g_dv_timings() - G_DV_TIMINGS handler + * @file: file ptr + * @priv: file handle + * @timings: digital video timings + */ +static int vpif_g_dv_timings(struct file *file, void *priv, + struct v4l2_dv_timings *timings) +{ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct video_obj *vid_ch = &ch->video; + struct v4l2_bt_timings *bt = &vid_ch->bt_timings; + + timings->bt = *bt; + + return 0; +} + +/* + * vpif_g_chip_ident() - Identify the chip + * @file: file ptr + * @priv: file handle + * @chip: chip identity + * + * Returns zero or -EINVAL if read operations fails. + */ +static int vpif_g_chip_ident(struct file *file, void *priv, + struct v4l2_dbg_chip_ident *chip) +{ + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && + chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) { + vpif_dbg(2, debug, "match_type is invalid.\n"); + return -EINVAL; + } + + return v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 0, core, + g_chip_ident, chip); +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +/* + * vpif_dbg_g_register() - Read register + * @file: file ptr + * @priv: file handle + * @reg: register to be read + * + * Debugging only + * Returns zero or -EINVAL if read operations fails. + */ +static int vpif_dbg_g_register(struct file *file, void *priv, + struct v4l2_dbg_register *reg){ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct video_obj *vid_ch = &ch->video; + + return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core, + g_register, reg); +} + +/* + * vpif_dbg_s_register() - Write to register + * @file: file ptr + * @priv: file handle + * @reg: register to be modified + * + * Debugging only + * Returns zero or -EINVAL if write operations fails. + */ +static int vpif_dbg_s_register(struct file *file, void *priv, + struct v4l2_dbg_register *reg){ + struct vpif_fh *fh = priv; + struct channel_obj *ch = fh->channel; + struct video_obj *vid_ch = &ch->video; + + return v4l2_subdev_call(vpif_obj.sd[vid_ch->output_id], core, + s_register, reg); +} +#endif + +/* + * vpif_log_status() - Status information + * @file: file ptr + * @priv: file handle + * + * Returns zero. + */ +static int vpif_log_status(struct file *filep, void *priv) +{ + /* status for sub devices */ + v4l2_device_call_all(&vpif_obj.v4l2_dev, 0, core, log_status); + + return 0; +} + /* vpif display ioctl operations */ static const struct v4l2_ioctl_ops vpif_ioctl_ops = { .vidioc_querycap = vpif_querycap, @@ -1336,13 +1582,24 @@ static const struct v4l2_ioctl_ops vpif_ioctl_ops = { .vidioc_s_output = vpif_s_output, .vidioc_g_output = vpif_g_output, .vidioc_cropcap = vpif_cropcap, + .vidioc_enum_dv_presets = vpif_enum_dv_presets, + .vidioc_s_dv_preset = vpif_s_dv_preset, + .vidioc_g_dv_preset = vpif_g_dv_preset, + .vidioc_s_dv_timings = vpif_s_dv_timings, + .vidioc_g_dv_timings = vpif_g_dv_timings, + .vidioc_g_chip_ident = vpif_g_chip_ident, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vpif_dbg_g_register, + .vidioc_s_register = vpif_dbg_s_register, +#endif + .vidioc_log_status = vpif_log_status, }; static const struct v4l2_file_operations vpif_fops = { .owner = THIS_MODULE, .open = vpif_open, .release = vpif_release, - .ioctl = video_ioctl2, + .unlocked_ioctl = video_ioctl2, .mmap = vpif_mmap, .poll = vpif_poll }; @@ -1526,6 +1783,7 @@ static __init int vpif_probe(struct platform_device *pdev) v4l2_prio_init(&ch->prio); ch->common[VPIF_VIDEO_INDEX].fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + ch->video_dev->lock = &common->lock; /* register video device */ vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n", @@ -1565,6 +1823,8 @@ static __init int vpif_probe(struct platform_device *pdev) vpif_obj.sd[i]->grp_id = 1 << i; } + v4l2_info(&vpif_obj.v4l2_dev, + "DM646x VPIF display driver initialized\n"); return 0; probe_subdev_out: diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/video/davinci/vpif_display.h index a2a7cd1..b53aaa8 100644 --- a/drivers/media/video/davinci/vpif_display.h +++ b/drivers/media/video/davinci/vpif_display.h @@ -67,6 +67,8 @@ struct video_obj { * most recent displayed frame only */ v4l2_std_id stdid; /* Currently selected or default * standard */ + u32 dv_preset; + struct v4l2_bt_timings bt_timings; u32 output_id; /* Current output id */ }; diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 099d5df..87f77a3 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -33,6 +33,7 @@ #include <media/saa7115.h> #include <media/tvp5150.h> #include <media/tvaudio.h> +#include <media/mt9v011.h> #include <media/i2c-addr.h> #include <media/tveeprom.h> #include <media/v4l2-common.h> @@ -1917,11 +1918,6 @@ static unsigned short tvp5150_addrs[] = { I2C_CLIENT_END }; -static unsigned short mt9v011_addrs[] = { - 0xba >> 1, - I2C_CLIENT_END -}; - static unsigned short msp3400_addrs[] = { 0x80 >> 1, 0x88 >> 1, @@ -2437,6 +2433,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev) dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW; dev->init_data.get_key = em28xx_get_key_em_haup; dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; + break; case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE; dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe; @@ -2623,11 +2620,17 @@ void em28xx_card_setup(struct em28xx *dev) "tvp5150", 0, tvp5150_addrs); if (dev->em28xx_sensor == EM28XX_MT9V011) { + struct mt9v011_platform_data pdata; + struct i2c_board_info mt9v011_info = { + .type = "mt9v011", + .addr = 0xba >> 1, + .platform_data = &pdata, + }; struct v4l2_subdev *sd; - sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_adap, "mt9v011", 0, mt9v011_addrs); - v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); + pdata.xtal = dev->sensor_xtal; + sd = v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap, + &mt9v011_info, NULL); } diff --git a/drivers/media/video/et61x251/et61x251.h b/drivers/media/video/et61x251/et61x251.h index cc77d14..bf66189 100644 --- a/drivers/media/video/et61x251/et61x251.h +++ b/drivers/media/video/et61x251/et61x251.h @@ -59,31 +59,7 @@ /*****************************************************************************/ static const struct usb_device_id et61x251_id_table[] = { - { USB_DEVICE(0x102c, 0x6151), }, { USB_DEVICE(0x102c, 0x6251), }, - { USB_DEVICE(0x102c, 0x6253), }, - { USB_DEVICE(0x102c, 0x6254), }, - { USB_DEVICE(0x102c, 0x6255), }, - { USB_DEVICE(0x102c, 0x6256), }, - { USB_DEVICE(0x102c, 0x6257), }, - { USB_DEVICE(0x102c, 0x6258), }, - { USB_DEVICE(0x102c, 0x6259), }, - { USB_DEVICE(0x102c, 0x625a), }, - { USB_DEVICE(0x102c, 0x625b), }, - { USB_DEVICE(0x102c, 0x625c), }, - { USB_DEVICE(0x102c, 0x625d), }, - { USB_DEVICE(0x102c, 0x625e), }, - { USB_DEVICE(0x102c, 0x625f), }, - { USB_DEVICE(0x102c, 0x6260), }, - { USB_DEVICE(0x102c, 0x6261), }, - { USB_DEVICE(0x102c, 0x6262), }, - { USB_DEVICE(0x102c, 0x6263), }, - { USB_DEVICE(0x102c, 0x6264), }, - { USB_DEVICE(0x102c, 0x6265), }, - { USB_DEVICE(0x102c, 0x6266), }, - { USB_DEVICE(0x102c, 0x6267), }, - { USB_DEVICE(0x102c, 0x6268), }, - { USB_DEVICE(0x102c, 0x6269), }, { } }; diff --git a/drivers/media/video/gspca/benq.c b/drivers/media/video/gspca/benq.c index 6290439..a09c470 100644 --- a/drivers/media/video/gspca/benq.c +++ b/drivers/media/video/gspca/benq.c @@ -276,7 +276,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x04a5, 0x3035)}, {} }; diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 1eacb6c..8b39849 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -1040,14 +1040,14 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const struct usb_device_id device_table[] __devinitconst = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0572, 0x0041)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int __devinit sd_probe(struct usb_interface *intf, +static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c index c1ae05f..4bf2cab 100644 --- a/drivers/media/video/gspca/cpia1.c +++ b/drivers/media/video/gspca/cpia1.c @@ -2088,7 +2088,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0553, 0x0002)}, {USB_DEVICE(0x0813, 0x0001)}, {} diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index a594b36..4b2c483 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -864,7 +864,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const struct usb_device_id device_table[] __devinitconst = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, #if !defined CONFIG_USB_ET61X251 && !defined CONFIG_USB_ET61X251_MODULE {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, @@ -875,7 +875,7 @@ static const struct usb_device_id device_table[] __devinitconst = { MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int __devinit sd_probe(struct usb_interface *intf, +static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c index d782264..987b4b6 100644 --- a/drivers/media/video/gspca/finepix.c +++ b/drivers/media/video/gspca/finepix.c @@ -229,7 +229,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) } /* Table of supported USB devices */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x04cb, 0x0104)}, {USB_DEVICE(0x04cb, 0x0109)}, {USB_DEVICE(0x04cb, 0x010b)}, diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c index b05bec7..9908303 100644 --- a/drivers/media/video/gspca/gl860/gl860.c +++ b/drivers/media/video/gspca/gl860/gl860.c @@ -488,7 +488,7 @@ static void sd_callback(struct gspca_dev *gspca_dev) /*=================== USB driver structure initialisation ==================*/ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x05e3, 0x0503)}, {USB_DEVICE(0x05e3, 0xf191)}, {} diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 4429700..f21f2a2 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -55,7 +55,7 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 11, 0) +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 12, 0) #ifdef GSPCA_DEBUG int gspca_debug = D_ERR | D_PROBE; @@ -508,8 +508,8 @@ static int gspca_is_compressed(__u32 format) return 0; } -static int frame_alloc(struct gspca_dev *gspca_dev, - unsigned int count) +static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file, + enum v4l2_memory memory, unsigned int count) { struct gspca_frame *frame; unsigned int frsz; @@ -519,7 +519,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev, frsz = gspca_dev->cam.cam_mode[i].sizeimage; PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); frsz = PAGE_ALIGN(frsz); - gspca_dev->frsz = frsz; if (count >= GSPCA_MAX_FRAMES) count = GSPCA_MAX_FRAMES - 1; gspca_dev->frbuf = vmalloc_32(frsz * count); @@ -527,6 +526,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev, err("frame alloc failed"); return -ENOMEM; } + gspca_dev->capt_file = file; + gspca_dev->memory = memory; + gspca_dev->frsz = frsz; gspca_dev->nframes = count; for (i = 0; i < count; i++) { frame = &gspca_dev->frame[i]; @@ -535,7 +537,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, frame->v4l2_buf.flags = 0; frame->v4l2_buf.field = V4L2_FIELD_NONE; frame->v4l2_buf.length = frsz; - frame->v4l2_buf.memory = gspca_dev->memory; + frame->v4l2_buf.memory = memory; frame->v4l2_buf.sequence = 0; frame->data = gspca_dev->frbuf + i * frsz; frame->v4l2_buf.m.offset = i * frsz; @@ -558,6 +560,9 @@ static void frame_free(struct gspca_dev *gspca_dev) gspca_dev->frame[i].data = NULL; } gspca_dev->nframes = 0; + gspca_dev->frsz = 0; + gspca_dev->capt_file = NULL; + gspca_dev->memory = GSPCA_MEMORY_NO; } static void destroy_urbs(struct gspca_dev *gspca_dev) @@ -1210,29 +1215,15 @@ static void gspca_release(struct video_device *vfd) static int dev_open(struct file *file) { struct gspca_dev *gspca_dev; - int ret; PDEBUG(D_STREAM, "[%s] open", current->comm); gspca_dev = (struct gspca_dev *) video_devdata(file); - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - if (!gspca_dev->present) { - ret = -ENODEV; - goto out; - } - - if (gspca_dev->users > 4) { /* (arbitrary value) */ - ret = -EBUSY; - goto out; - } + if (!gspca_dev->present) + return -ENODEV; /* protect the subdriver against rmmod */ - if (!try_module_get(gspca_dev->module)) { - ret = -ENODEV; - goto out; - } - - gspca_dev->users++; + if (!try_module_get(gspca_dev->module)) + return -ENODEV; file->private_data = gspca_dev; #ifdef GSPCA_DEBUG @@ -1244,14 +1235,7 @@ static int dev_open(struct file *file) gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG); #endif - ret = 0; -out: - mutex_unlock(&gspca_dev->queue_lock); - if (ret != 0) - PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret); - else - PDEBUG(D_STREAM, "open done"); - return ret; + return 0; } static int dev_close(struct file *file) @@ -1261,7 +1245,6 @@ static int dev_close(struct file *file) PDEBUG(D_STREAM, "[%s] close", current->comm); if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - gspca_dev->users--; /* if the file did the capture, free the streaming resources */ if (gspca_dev->capt_file == file) { @@ -1272,8 +1255,6 @@ static int dev_close(struct file *file) mutex_unlock(&gspca_dev->usb_lock); } frame_free(gspca_dev); - gspca_dev->capt_file = NULL; - gspca_dev->memory = GSPCA_MEMORY_NO; } file->private_data = NULL; module_put(gspca_dev->module); @@ -1516,6 +1497,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, return -ERESTARTSYS; if (gspca_dev->memory != GSPCA_MEMORY_NO + && gspca_dev->memory != GSPCA_MEMORY_READ && gspca_dev->memory != rb->memory) { ret = -EBUSY; goto out; @@ -1544,19 +1526,18 @@ static int vidioc_reqbufs(struct file *file, void *priv, gspca_stream_off(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); } + /* Don't restart the stream when switching from read to mmap mode */ + if (gspca_dev->memory == GSPCA_MEMORY_READ) + streaming = 0; /* free the previous allocated buffers, if any */ - if (gspca_dev->nframes != 0) { + if (gspca_dev->nframes != 0) frame_free(gspca_dev); - gspca_dev->capt_file = NULL; - } if (rb->count == 0) /* unrequest */ goto out; - gspca_dev->memory = rb->memory; - ret = frame_alloc(gspca_dev, rb->count); + ret = frame_alloc(gspca_dev, file, rb->memory, rb->count); if (ret == 0) { rb->count = gspca_dev->nframes; - gspca_dev->capt_file = file; if (streaming) ret = gspca_init_transfer(gspca_dev); } @@ -1630,11 +1611,15 @@ static int vidioc_streamoff(struct file *file, void *priv, if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (!gspca_dev->streaming) - return 0; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; + if (!gspca_dev->streaming) { + ret = 0; + goto out; + } + /* check the capture file */ if (gspca_dev->capt_file != file) { ret = -EBUSY; @@ -1649,6 +1634,8 @@ static int vidioc_streamoff(struct file *file, void *priv, gspca_dev->usb_err = 0; gspca_stream_off(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); + /* In case another thread is waiting in dqbuf */ + wake_up_interruptible(&gspca_dev->wq); /* empty the transfer queues */ atomic_set(&gspca_dev->fr_q, 0); @@ -1827,33 +1814,77 @@ out: return ret; } +static int frame_ready_nolock(struct gspca_dev *gspca_dev, struct file *file, + enum v4l2_memory memory) +{ + if (!gspca_dev->present) + return -ENODEV; + if (gspca_dev->capt_file != file || gspca_dev->memory != memory || + !gspca_dev->streaming) + return -EINVAL; + + /* check if a frame is ready */ + return gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i); +} + +static int frame_ready(struct gspca_dev *gspca_dev, struct file *file, + enum v4l2_memory memory) +{ + int ret; + + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; + ret = frame_ready_nolock(gspca_dev, file, memory); + mutex_unlock(&gspca_dev->queue_lock); + return ret; +} + /* - * wait for a video frame + * dequeue a video buffer * - * If a frame is ready, its index is returned. + * If nonblock_ing is false, block until a buffer is available. */ -static int frame_wait(struct gspca_dev *gspca_dev, - int nonblock_ing) +static int vidioc_dqbuf(struct file *file, void *priv, + struct v4l2_buffer *v4l2_buf) { - int i, ret; + struct gspca_dev *gspca_dev = priv; + struct gspca_frame *frame; + int i, j, ret; - /* check if a frame is ready */ - i = gspca_dev->fr_o; - if (i == atomic_read(&gspca_dev->fr_i)) { - if (nonblock_ing) + PDEBUG(D_FRAM, "dqbuf"); + + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; + + for (;;) { + ret = frame_ready_nolock(gspca_dev, file, v4l2_buf->memory); + if (ret < 0) + goto out; + if (ret > 0) + break; + + mutex_unlock(&gspca_dev->queue_lock); + + if (file->f_flags & O_NONBLOCK) return -EAGAIN; /* wait till a frame is ready */ ret = wait_event_interruptible_timeout(gspca_dev->wq, - i != atomic_read(&gspca_dev->fr_i) || - !gspca_dev->streaming || !gspca_dev->present, + frame_ready(gspca_dev, file, v4l2_buf->memory), msecs_to_jiffies(3000)); if (ret < 0) return ret; - if (ret == 0 || !gspca_dev->streaming || !gspca_dev->present) + if (ret == 0) return -EIO; + + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; } + i = gspca_dev->fr_o; + j = gspca_dev->fr_queue[i]; + frame = &gspca_dev->frame[j]; + gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES; if (gspca_dev->sd_desc->dq_callback) { @@ -1863,46 +1894,12 @@ static int frame_wait(struct gspca_dev *gspca_dev, gspca_dev->sd_desc->dq_callback(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); } - return gspca_dev->fr_queue[i]; -} - -/* - * dequeue a video buffer - * - * If nonblock_ing is false, block until a buffer is available. - */ -static int vidioc_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *v4l2_buf) -{ - struct gspca_dev *gspca_dev = priv; - struct gspca_frame *frame; - int i, ret; - - PDEBUG(D_FRAM, "dqbuf"); - if (v4l2_buf->memory != gspca_dev->memory) - return -EINVAL; - - if (!gspca_dev->present) - return -ENODEV; - - /* if not streaming, be sure the application will not loop forever */ - if (!(file->f_flags & O_NONBLOCK) - && !gspca_dev->streaming && gspca_dev->users == 1) - return -EINVAL; - /* only the capturing file may dequeue */ - if (gspca_dev->capt_file != file) - return -EINVAL; - - /* only one dequeue / read at a time */ - if (mutex_lock_interruptible(&gspca_dev->read_lock)) - return -ERESTARTSYS; + frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; + memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); + PDEBUG(D_FRAM, "dqbuf %d", j); + ret = 0; - ret = frame_wait(gspca_dev, file->f_flags & O_NONBLOCK); - if (ret < 0) - goto out; - i = ret; /* frame index */ - frame = &gspca_dev->frame[i]; if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr, frame->data, @@ -1910,15 +1907,10 @@ static int vidioc_dqbuf(struct file *file, void *priv, PDEBUG(D_ERR|D_STREAM, "dqbuf cp to user failed"); ret = -EFAULT; - goto out; } } - frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; - memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); - PDEBUG(D_FRAM, "dqbuf %d", i); - ret = 0; out: - mutex_unlock(&gspca_dev->read_lock); + mutex_unlock(&gspca_dev->queue_lock); return ret; } @@ -2033,9 +2025,7 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) poll_wait(file, &gspca_dev->wq, wait); /* if reqbufs is not done, the user would use read() */ - if (gspca_dev->nframes == 0) { - if (gspca_dev->memory != GSPCA_MEMORY_NO) - return POLLERR; /* not the 1st time */ + if (gspca_dev->memory == GSPCA_MEMORY_NO) { ret = read_alloc(gspca_dev, file); if (ret != 0) return POLLERR; @@ -2067,18 +2057,10 @@ static ssize_t dev_read(struct file *file, char __user *data, PDEBUG(D_FRAM, "read (%zd)", count); if (!gspca_dev->present) return -ENODEV; - switch (gspca_dev->memory) { - case GSPCA_MEMORY_NO: /* first time */ + if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */ ret = read_alloc(gspca_dev, file); if (ret != 0) return ret; - break; - case GSPCA_MEMORY_READ: - if (gspca_dev->capt_file == file) - break; - /* fall thru */ - default: - return -EINVAL; } /* get a frame */ @@ -2266,7 +2248,6 @@ int gspca_dev_probe2(struct usb_interface *intf, goto out; mutex_init(&gspca_dev->usb_lock); - mutex_init(&gspca_dev->read_lock); mutex_init(&gspca_dev->queue_lock); init_waitqueue_head(&gspca_dev->wq); @@ -2341,12 +2322,11 @@ void gspca_disconnect(struct usb_interface *intf) PDEBUG(D_PROBE, "%s disconnect", video_device_node_name(&gspca_dev->vdev)); mutex_lock(&gspca_dev->usb_lock); + gspca_dev->present = 0; + wake_up_interruptible(&gspca_dev->wq); - if (gspca_dev->streaming) { - destroy_urbs(gspca_dev); - wake_up_interruptible(&gspca_dev->wq); - } + destroy_urbs(gspca_dev); #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) gspca_input_destroy_urb(gspca_dev); diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 97b77a2..4175522 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -205,14 +205,12 @@ struct gspca_dev { wait_queue_head_t wq; /* wait queue */ struct mutex usb_lock; /* usb exchange protection */ - struct mutex read_lock; /* read protection */ struct mutex queue_lock; /* ISOC queue protection */ int usb_err; /* USB error - protected by usb_lock */ u16 pkt_size; /* ISOC packet size */ #ifdef CONFIG_PM char frozen; /* suspend - resume */ #endif - char users; /* number of opens */ char present; /* device connected */ char nbufread; /* number of buffers for read() */ char memory; /* memory type (V4L2_MEMORY_xxx) */ diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c index a35e87b..06b777f 100644 --- a/drivers/media/video/gspca/jeilinj.c +++ b/drivers/media/video/gspca/jeilinj.c @@ -314,7 +314,7 @@ static int sd_start(struct gspca_dev *gspca_dev) } /* Table of supported USB devices */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0979, 0x0280)}, {} }; diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h index de63c36..ab54910 100644 --- a/drivers/media/video/gspca/jpeg.h +++ b/drivers/media/video/gspca/jpeg.h @@ -141,9 +141,9 @@ static void jpeg_define(u8 *jpeg_hdr, memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head); #ifndef CONEX_CAM jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height & 0xff; + jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height; jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8; - jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width & 0xff; + jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width; jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY; #endif } diff --git a/drivers/media/video/gspca/konica.c b/drivers/media/video/gspca/konica.c index d2ce65d..5964691 100644 --- a/drivers/media/video/gspca/konica.c +++ b/drivers/media/video/gspca/konica.c @@ -607,7 +607,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x04c8, 0x0720)}, /* Intel YC 76 */ {} }; diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c index c872b93..a7722b1 100644 --- a/drivers/media/video/gspca/m5602/m5602_core.c +++ b/drivers/media/video/gspca/m5602/m5602_core.c @@ -28,7 +28,7 @@ int force_sensor; static int dump_bridge; int dump_sensor; -static const __devinitdata struct usb_device_id m5602_table[] = { +static const struct usb_device_id m5602_table[] = { {USB_DEVICE(0x0402, 0x5602)}, {} }; diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index a81536e..cb4d0bf 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -490,7 +490,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x050f)}, {} }; diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c index 7607a28..3884c9d 100644 --- a/drivers/media/video/gspca/mr97310a.c +++ b/drivers/media/video/gspca/mr97310a.c @@ -1229,7 +1229,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x08ca, 0x0110)}, /* Trust Spyc@m 100 */ {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */ {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */ diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index e1c3b93..8ab2c45 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -488,7 +488,6 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = { #define R511_SNAP_PXDIV 0x1c #define R511_SNAP_LNDIV 0x1d #define R511_SNAP_UV_EN 0x1e -#define R511_SNAP_UV_EN 0x1e #define R511_SNAP_OPTS 0x1f #define R511_DRAM_FLOW_CTL 0x20 @@ -1847,8 +1846,7 @@ static const struct ov_i2c_regvals norm_7670[] = { { 0x6c, 0x0a }, { 0x6d, 0x55 }, { 0x6e, 0x11 }, - { 0x6f, 0x9f }, - /* "9e for advance AWB" */ + { 0x6f, 0x9f }, /* "9e for advance AWB" */ { 0x6a, 0x40 }, { OV7670_R01_BLUE, 0x40 }, { OV7670_R02_RED, 0x60 }, @@ -3054,7 +3052,7 @@ static void ov519_configure(struct sd *sd) { static const struct ov_regvals init_519[] = { { 0x5a, 0x6d }, /* EnableSystem */ - { 0x53, 0x9b }, + { 0x53, 0x9b }, /* don't enable the microcontroller */ { OV519_R54_EN_CLK1, 0xff }, /* set bit2 to enable jpeg */ { 0x5d, 0x03 }, { 0x49, 0x01 }, @@ -4747,7 +4745,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4003), .driver_info = BRIDGE_W9968CF }, {USB_DEVICE(0x041e, 0x4052), .driver_info = BRIDGE_OV519 }, {USB_DEVICE(0x041e, 0x405f), .driver_info = BRIDGE_OV519 }, diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 0edf939..04da228 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -479,15 +479,20 @@ static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) struct usb_device *udev = gspca_dev->dev; int ret; - PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val); + if (gspca_dev->usb_err < 0) + return; + + PDEBUG(D_USBO, "SET 01 0000 %04x %02x", reg, val); gspca_dev->usb_buf[0] = val; ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); - if (ret < 0) + if (ret < 0) { err("write failed %d", ret); + gspca_dev->usb_err = ret; + } } static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) @@ -495,14 +500,18 @@ static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) struct usb_device *udev = gspca_dev->dev; int ret; + if (gspca_dev->usb_err < 0) + return 0; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x01, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); - PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]); - if (ret < 0) + PDEBUG(D_USBI, "GET 01 0000 %04x %02x", reg, gspca_dev->usb_buf[0]); + if (ret < 0) { err("read failed %d", ret); + gspca_dev->usb_err = ret; + } return gspca_dev->usb_buf[0]; } @@ -558,13 +567,15 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val) { - PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val); + PDEBUG(D_USBO, "sccb write: %02x %02x", reg, val); ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); ov534_reg_write(gspca_dev, OV534_REG_WRITE, val); ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); - if (!sccb_check_status(gspca_dev)) + if (!sccb_check_status(gspca_dev)) { err("sccb_reg_write failed"); + gspca_dev->usb_err = -EIO; + } } static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) @@ -885,7 +896,7 @@ static int sd_init(struct gspca_dev *gspca_dev) ov534_set_led(gspca_dev, 0); set_frame_rate(gspca_dev); - return 0; + return gspca_dev->usb_err; } static int sd_start(struct gspca_dev *gspca_dev) @@ -920,7 +931,7 @@ static int sd_start(struct gspca_dev *gspca_dev) ov534_set_led(gspca_dev, 1); ov534_reg_write(gspca_dev, 0xe0, 0x00); - return 0; + return gspca_dev->usb_err; } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -1289,7 +1300,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x1415, 0x2000)}, {} }; diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index c5244b4..aaf5428 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c @@ -1429,7 +1429,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x06f8, 0x3003)}, {} }; diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 96f9986..81739a2 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -530,7 +530,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4028)}, {USB_DEVICE(0x093a, 0x2460)}, {USB_DEVICE(0x093a, 0x2461)}, diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c index 2700975..5615d7b 100644 --- a/drivers/media/video/gspca/pac7302.c +++ b/drivers/media/video/gspca/pac7302.c @@ -1184,7 +1184,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const struct usb_device_id device_table[] __devinitconst = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x06f8, 0x3009)}, {USB_DEVICE(0x093a, 0x2620)}, {USB_DEVICE(0x093a, 0x2621)}, @@ -1201,7 +1201,7 @@ static const struct usb_device_id device_table[] __devinitconst = { MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int __devinit sd_probe(struct usb_interface *intf, +static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 6820f5d..f8801b5 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -837,7 +837,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const struct usb_device_id device_table[] __devinitconst = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2600)}, {USB_DEVICE(0x093a, 0x2601)}, {USB_DEVICE(0x093a, 0x2603)}, @@ -849,7 +849,7 @@ static const struct usb_device_id device_table[] __devinitconst = { MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int __devinit sd_probe(struct usb_interface *intf, +static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/sn9c2028.c b/drivers/media/video/gspca/sn9c2028.c index 40a0668..4271f86 100644 --- a/drivers/media/video/gspca/sn9c2028.c +++ b/drivers/media/video/gspca/sn9c2028.c @@ -703,7 +703,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0458, 0x7005)}, /* Genius Smart 300, version 2 */ /* The Genius Smart is untested. I can't find an owner ! */ /* {USB_DEVICE(0x0c45, 0x8000)}, DC31VC, Don't know this camera */ diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index cb08d00..fcf2989 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -2470,7 +2470,7 @@ static const struct sd_desc sd_desc = { | (SENSOR_ ## sensor << 8) \ | (i2c_addr) -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)}, {USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)}, {USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)}, diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 73504a3..c6cd68d 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -23,8 +23,15 @@ /* Some documentation on known sonixb registers: Reg Use +sn9c101 / sn9c102: 0x10 high nibble red gain low nibble blue gain 0x11 low nibble green gain +sn9c103: +0x05 red gain 0-127 +0x06 blue gain 0-127 +0x07 green gain 0-127 +all: +0x08-0x0f i2c / 3wire registers 0x12 hstart 0x13 vstart 0x15 hsize (hsize = register-value * 16) @@ -88,12 +95,9 @@ struct sd { typedef const __u8 sensor_init_t[8]; struct sensor_data { - const __u8 *bridge_init[2]; - int bridge_init_size[2]; + const __u8 *bridge_init; sensor_init_t *sensor_init; int sensor_init_size; - sensor_init_t *sensor_bridge_init[2]; - int sensor_bridge_init_size[2]; int flags; unsigned ctrl_dis; __u8 sensor_addr; @@ -114,7 +118,6 @@ struct sensor_data { #define NO_FREQ (1 << FREQ_IDX) #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX) -#define COMP2 0x8f #define COMP 0xc7 /* 0x87 //0x07 */ #define COMP1 0xc9 /* 0x89 //0x09 */ @@ -123,15 +126,11 @@ struct sensor_data { #define SYS_CLK 0x04 -#define SENS(bridge_1, bridge_3, sensor, sensor_1, \ - sensor_3, _flags, _ctrl_dis, _sensor_addr) \ +#define SENS(bridge, sensor, _flags, _ctrl_dis, _sensor_addr) \ { \ - .bridge_init = { bridge_1, bridge_3 }, \ - .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \ + .bridge_init = bridge, \ .sensor_init = sensor, \ .sensor_init_size = sizeof(sensor), \ - .sensor_bridge_init = { sensor_1, sensor_3,}, \ - .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \ .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \ } @@ -311,7 +310,6 @@ static const __u8 initHv7131d[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x28, 0x1e, 0x60, 0x8e, 0x42, - 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c }; static const __u8 hv7131d_sensor_init[][8] = { {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17}, @@ -326,7 +324,6 @@ static const __u8 initHv7131r[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x28, 0x1e, 0x60, 0x8a, 0x20, - 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c }; static const __u8 hv7131r_sensor_init[][8] = { {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, @@ -339,7 +336,7 @@ static const __u8 initOv6650[] = { 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b, - 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07 + 0x10, }; static const __u8 ov6650_sensor_init[][8] = { /* Bright, contrast, etc are set through SCBB interface. @@ -378,24 +375,13 @@ static const __u8 initOv7630[] = { 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ 0x28, 0x1e, /* H & V sizes r15 .. r16 */ - 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */ - 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ -}; -static const __u8 initOv7630_3[] = { - 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ - 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ - 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ - 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ - 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ - 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ }; static const __u8 ov7630_sensor_init[][8] = { {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ - {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */ + {0xd0, 0x21, 0x12, 0x5c, 0x00, 0x80, 0x34, 0x10}, /* jfm */ {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, @@ -413,16 +399,11 @@ static const __u8 ov7630_sensor_init[][8] = { {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, }; -static const __u8 ov7630_sensor_init_3[][8] = { - {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10}, -}; - static const __u8 initPas106[] = { 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x16, 0x12, 0x24, COMP1, MCK_INIT1, - 0x18, 0x10, 0x02, 0x02, 0x09, 0x07 }; /* compression 0x86 mckinit1 0x2b */ @@ -496,7 +477,6 @@ static const __u8 initPas202[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a, 0x28, 0x1e, 0x20, 0x89, 0x20, - 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c }; /* "Known" PAS202BCB registers: @@ -537,7 +517,6 @@ static const __u8 initTas5110c[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a, 0x16, 0x12, 0x60, 0x86, 0x2b, - 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 }; /* Same as above, except a different hstart */ static const __u8 initTas5110d[] = { @@ -545,12 +524,19 @@ static const __u8 initTas5110d[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a, 0x16, 0x12, 0x60, 0x86, 0x2b, - 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 }; -static const __u8 tas5110_sensor_init[][8] = { +/* tas5110c is 3 wire, tas5110d is 2 wire (regular i2c) */ +static const __u8 tas5110c_sensor_init[][8] = { {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10}, {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10}, - {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, +}; +/* Known TAS5110D registers + * reg02: gain, bit order reversed!! 0 == max gain, 255 == min gain + * reg03: bit3: vflip, bit4: ~hflip, bit7: ~gainboost (~ == inverted) + * Note: writing reg03 seems to only work when written together with 02 + */ +static const __u8 tas5110d_sensor_init[][8] = { + {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, /* reset */ }; static const __u8 initTas5130[] = { @@ -558,7 +544,6 @@ static const __u8 initTas5130[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a, 0x28, 0x1e, 0x60, COMP, MCK_INIT, - 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c }; static const __u8 tas5130_sensor_init[][8] = { /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, @@ -569,21 +554,18 @@ static const __u8 tas5130_sensor_init[][8] = { }; static struct sensor_data sensor_data[] = { -SENS(initHv7131d, NULL, hv7131d_sensor_init, NULL, NULL, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), -SENS(initHv7131r, NULL, hv7131r_sensor_init, NULL, NULL, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), -SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60), -SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3, - F_GAIN, 0, 0x21), -SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ, - 0), -SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN, - NO_FREQ, 0), -SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL, - F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0), -SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL, - F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0), -SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, - 0), +SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), +SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), +SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60), +SENS(initOv7630, ov7630_sensor_init, F_GAIN, 0, 0x21), +SENS(initPas106, pas106_sensor_init, F_GAIN|F_SIF, NO_FREQ, 0), +SENS(initPas202, pas202_sensor_init, F_GAIN, NO_FREQ, 0), +SENS(initTas5110c, tas5110c_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO, + NO_BRIGHTNESS|NO_FREQ, 0), +SENS(initTas5110d, tas5110d_sensor_init, F_GAIN|F_SIF|F_COARSE_EXPO, + NO_BRIGHTNESS|NO_FREQ, 0), +SENS(initTas5130, tas5130_sensor_init, F_GAIN, + NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), }; /* get one byte in gspca_dev->usb_buf */ @@ -655,7 +637,6 @@ static void i2c_w_vector(struct gspca_dev *gspca_dev, static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 value; switch (sd->sensor) { case SENSOR_OV6650: @@ -697,17 +678,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) goto err; break; } - case SENSOR_TAS5130CXX: { - __u8 i2c[] = - {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; - - value = 0xff - sd->brightness; - i2c[4] = value; - PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]); - if (i2c_w(gspca_dev, i2c) < 0) - goto err; - break; - } } return; err: @@ -733,7 +703,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev) break; } case SENSOR_TAS5110C: - case SENSOR_TAS5110D: { + case SENSOR_TAS5130CXX: { __u8 i2c[] = {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; @@ -742,6 +712,23 @@ static void setsensorgain(struct gspca_dev *gspca_dev) goto err; break; } + case SENSOR_TAS5110D: { + __u8 i2c[] = { + 0xb0, 0x61, 0x02, 0x00, 0x10, 0x00, 0x00, 0x17 }; + gain = 255 - gain; + /* The bits in the register are the wrong way around!! */ + i2c[3] |= (gain & 0x80) >> 7; + i2c[3] |= (gain & 0x40) >> 5; + i2c[3] |= (gain & 0x20) >> 3; + i2c[3] |= (gain & 0x10) >> 1; + i2c[3] |= (gain & 0x08) << 1; + i2c[3] |= (gain & 0x04) << 3; + i2c[3] |= (gain & 0x02) << 5; + i2c[3] |= (gain & 0x01) << 7; + if (i2c_w(gspca_dev, i2c) < 0) + goto err; + break; + } case SENSOR_OV6650: gain >>= 1; @@ -796,7 +783,7 @@ static void setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u8 gain; - __u8 buf[2] = { 0, 0 }; + __u8 buf[3] = { 0, 0, 0 }; if (sensor_data[sd->sensor].flags & F_GAIN) { /* Use the sensor gain to do the actual gain */ @@ -804,13 +791,18 @@ static void setgain(struct gspca_dev *gspca_dev) return; } - gain = sd->gain >> 4; - - /* red and blue gain */ - buf[0] = gain << 4 | gain; - /* green gain */ - buf[1] = gain; - reg_w(gspca_dev, 0x10, buf, 2); + if (sd->bridge == BRIDGE_103) { + gain = sd->gain >> 1; + buf[0] = gain; /* Red */ + buf[1] = gain; /* Green */ + buf[2] = gain; /* Blue */ + reg_w(gspca_dev, 0x05, buf, 3); + } else { + gain = sd->gain >> 4; + buf[0] = gain << 4 | gain; /* Red and blue */ + buf[1] = gain; /* Green */ + reg_w(gspca_dev, 0x10, buf, 2); + } } static void setexposure(struct gspca_dev *gspca_dev) @@ -1049,7 +1041,7 @@ static void do_autogain(struct gspca_dev *gspca_dev) desired_avg_lum = 5000; } else { deadzone = 1500; - desired_avg_lum = 18000; + desired_avg_lum = 13000; } if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) @@ -1127,53 +1119,91 @@ static int sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam = &gspca_dev->cam; - int mode, l; - const __u8 *sn9c10x; - __u8 reg12_19[8]; + int i, mode; + __u8 regs[0x31]; mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07; - sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge]; - l = sensor_data[sd->sensor].bridge_init_size[sd->bridge]; - memcpy(reg12_19, &sn9c10x[0x12 - 1], 8); - reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4); - /* Special cases where reg 17 and or 19 value depends on mode */ + /* Copy registers 0x01 - 0x19 from the template */ + memcpy(®s[0x01], sensor_data[sd->sensor].bridge_init, 0x19); + /* Set the mode */ + regs[0x18] |= mode << 4; + + /* Set bridge gain to 1.0 */ + if (sd->bridge == BRIDGE_103) { + regs[0x05] = 0x20; /* Red */ + regs[0x06] = 0x20; /* Green */ + regs[0x07] = 0x20; /* Blue */ + } else { + regs[0x10] = 0x00; /* Red and blue */ + regs[0x11] = 0x00; /* Green */ + } + + /* Setup pixel numbers and auto exposure window */ + if (sensor_data[sd->sensor].flags & F_SIF) { + regs[0x1a] = 0x14; /* HO_SIZE 640, makes no sense */ + regs[0x1b] = 0x0a; /* VO_SIZE 320, makes no sense */ + regs[0x1c] = 0x02; /* AE H-start 64 */ + regs[0x1d] = 0x02; /* AE V-start 64 */ + regs[0x1e] = 0x09; /* AE H-end 288 */ + regs[0x1f] = 0x07; /* AE V-end 224 */ + } else { + regs[0x1a] = 0x1d; /* HO_SIZE 960, makes no sense */ + regs[0x1b] = 0x10; /* VO_SIZE 512, makes no sense */ + regs[0x1c] = 0x05; /* AE H-start 160 */ + regs[0x1d] = 0x03; /* AE V-start 96 */ + regs[0x1e] = 0x0f; /* AE H-end 480 */ + regs[0x1f] = 0x0c; /* AE V-end 384 */ + } + + /* Setup the gamma table (only used with the sn9c103 bridge) */ + for (i = 0; i < 16; i++) + regs[0x20 + i] = i * 16; + regs[0x20 + i] = 255; + + /* Special cases where some regs depend on mode or bridge */ switch (sd->sensor) { case SENSOR_TAS5130CXX: - /* probably not mode specific at all most likely the upper + /* FIXME / TESTME + probably not mode specific at all most likely the upper nibble of 0x19 is exposure (clock divider) just as with the tas5110, we need someone to test this. */ - reg12_19[7] = mode ? 0x23 : 0x43; + regs[0x19] = mode ? 0x23 : 0x43; break; + case SENSOR_OV7630: + /* FIXME / TESTME for some reason with the 101/102 bridge the + clock is set to 12 Mhz (reg1 == 0x04), rather then 24. + Also the hstart needs to go from 1 to 2 when using a 103, + which is likely related. This does not seem right. */ + if (sd->bridge == BRIDGE_103) { + regs[0x01] = 0x44; /* Select 24 Mhz clock */ + regs[0x12] = 0x02; /* Set hstart to 2 */ + } } /* Disable compression when the raw bayer format has been selected */ if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) - reg12_19[6] &= ~0x80; + regs[0x18] &= ~0x80; /* Vga mode emulation on SIF sensor? */ if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) { - reg12_19[0] += 16; /* 0x12: hstart adjust */ - reg12_19[1] += 24; /* 0x13: vstart adjust */ - reg12_19[3] = 320 / 16; /* 0x15: hsize */ - reg12_19[4] = 240 / 16; /* 0x16: vsize */ + regs[0x12] += 16; /* hstart adjust */ + regs[0x13] += 24; /* vstart adjust */ + regs[0x15] = 320 / 16; /* hsize */ + regs[0x16] = 240 / 16; /* vsize */ } /* reg 0x01 bit 2 video transfert on */ - reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); + reg_w(gspca_dev, 0x01, ®s[0x01], 1); /* reg 0x17 SensorClk enable inv Clk 0x60 */ - reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); + reg_w(gspca_dev, 0x17, ®s[0x17], 1); /* Set the registers from the template */ - reg_w(gspca_dev, 0x01, sn9c10x, l); + reg_w(gspca_dev, 0x01, ®s[0x01], + (sd->bridge == BRIDGE_103) ? 0x30 : 0x1f); /* Init the sensor */ i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init, sensor_data[sd->sensor].sensor_init_size); - if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge]) - i2c_w_vector(gspca_dev, - sensor_data[sd->sensor].sensor_bridge_init[sd->bridge], - sensor_data[sd->sensor].sensor_bridge_init_size[ - sd->bridge]); - /* Mode specific sensor setup */ + /* Mode / bridge specific sensor setup */ switch (sd->sensor) { case SENSOR_PAS202: { const __u8 i2cpclockdiv[] = @@ -1181,27 +1211,37 @@ static int sd_start(struct gspca_dev *gspca_dev) /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */ if (mode) i2c_w(gspca_dev, i2cpclockdiv); + break; } + case SENSOR_OV7630: + /* FIXME / TESTME We should be able to handle this identical + for the 101/102 and the 103 case */ + if (sd->bridge == BRIDGE_103) { + const __u8 i2c[] = { 0xa0, 0x21, 0x13, + 0x80, 0x00, 0x00, 0x00, 0x10 }; + i2c_w(gspca_dev, i2c); + } + break; } /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ - reg_w(gspca_dev, 0x15, ®12_19[3], 2); + reg_w(gspca_dev, 0x15, ®s[0x15], 2); /* compression register */ - reg_w(gspca_dev, 0x18, ®12_19[6], 1); + reg_w(gspca_dev, 0x18, ®s[0x18], 1); /* H_start */ - reg_w(gspca_dev, 0x12, ®12_19[0], 1); + reg_w(gspca_dev, 0x12, ®s[0x12], 1); /* V_START */ - reg_w(gspca_dev, 0x13, ®12_19[1], 1); + reg_w(gspca_dev, 0x13, ®s[0x13], 1); /* reset 0x17 SensorClk enable inv Clk 0x60 */ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ - reg_w(gspca_dev, 0x17, ®12_19[5], 1); + reg_w(gspca_dev, 0x17, ®s[0x17], 1); /*MCKSIZE ->3 */ /*fixme: not ov7630*/ - reg_w(gspca_dev, 0x19, ®12_19[7], 1); + reg_w(gspca_dev, 0x19, ®s[0x19], 1); /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ - reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); + reg_w(gspca_dev, 0x1c, ®s[0x1c], 4); /* Enable video transfert */ - reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); + reg_w(gspca_dev, 0x01, ®s[0x01], 1); /* Compression */ - reg_w(gspca_dev, 0x18, ®12_19[6], 2); + reg_w(gspca_dev, 0x18, ®s[0x18], 2); msleep(20); sd->reg11 = -1; @@ -1525,15 +1565,15 @@ static const struct sd_desc sd_desc = { .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge -static const struct usb_device_id device_table[] __devinitconst = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */ {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */ {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */ {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)}, {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)}, {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)}, -#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)}, +#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)}, {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)}, #endif @@ -1544,18 +1584,22 @@ static const struct usb_device_id device_table[] __devinitconst = { {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)}, {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)}, {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)}, - /* {USB_DEVICE(0x0c45, 0x602b), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */ + /* {USB_DEVICE(0x0c45, 0x6030), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */ + /* {USB_DEVICE(0x0c45, 0x6082), SB(MI03XX, 103)}, */ /* MI0343 MI0360 */ + {USB_DEVICE(0x0c45, 0x6083), SB(HV7131D, 103)}, + {USB_DEVICE(0x0c45, 0x608c), SB(HV7131R, 103)}, + /* {USB_DEVICE(0x0c45, 0x608e), SB(CISVF10, 103)}, */ {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)}, -#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE + {USB_DEVICE(0x0c45, 0x60a8), SB(PAS106, 103)}, + {USB_DEVICE(0x0c45, 0x60aa), SB(TAS5130CXX, 103)}, {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)}, -#endif {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ -static int __devinit sd_probe(struct usb_interface *intf, +static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 2d0bb17..d6f39ce 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -25,12 +25,12 @@ #include "gspca.h" #include "jpeg.h" -#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0) - MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>"); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); MODULE_LICENSE("GPL"); +static int starcam; + /* controls */ enum e_ctrl { BRIGHTNESS, @@ -43,7 +43,7 @@ enum e_ctrl { HFLIP, VFLIP, SHARPNESS, - INFRARED, + ILLUM, FREQ, NCTRLS /* number of controls */ }; @@ -100,7 +100,8 @@ enum sensors { }; /* device flags */ -#define PDN_INV 1 /* inverse pin S_PWR_DN / sn_xxx tables */ +#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */ +#define F_ILLUM 0x02 /* presence of illuminator */ /* sn9c1xx definitions */ /* register 0x01 */ @@ -124,7 +125,7 @@ static void setgamma(struct gspca_dev *gspca_dev); static void setautogain(struct gspca_dev *gspca_dev); static void sethvflip(struct gspca_dev *gspca_dev); static void setsharpness(struct gspca_dev *gspca_dev); -static void setinfrared(struct gspca_dev *gspca_dev); +static void setillum(struct gspca_dev *gspca_dev); static void setfreq(struct gspca_dev *gspca_dev); static const struct ctrl sd_ctrls[NCTRLS] = { @@ -251,18 +252,17 @@ static const struct ctrl sd_ctrls[NCTRLS] = { }, .set_control = setsharpness }, -/* mt9v111 only */ -[INFRARED] = { +[ILLUM] = { { - .id = V4L2_CID_INFRARED, + .id = V4L2_CID_ILLUMINATORS_1, .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Infrared", + .name = "Illuminator / infrared", .minimum = 0, .maximum = 1, .step = 1, .default_value = 0, }, - .set_control = setinfrared + .set_control = setillum }, /* ov7630/ov7648/ov7660 only */ [FREQ] = { @@ -282,32 +282,26 @@ static const struct ctrl sd_ctrls[NCTRLS] = { /* table of the disabled controls */ static const __u32 ctrl_dis[] = { [SENSOR_ADCM1700] = (1 << AUTOGAIN) | - (1 << INFRARED) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), -[SENSOR_GC0307] = (1 << INFRARED) | - (1 << HFLIP) | +[SENSOR_GC0307] = (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), -[SENSOR_HV7131R] = (1 << INFRARED) | - (1 << HFLIP) | +[SENSOR_HV7131R] = (1 << HFLIP) | (1 << FREQ), -[SENSOR_MI0360] = (1 << INFRARED) | - (1 << HFLIP) | +[SENSOR_MI0360] = (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), -[SENSOR_MI0360B] = (1 << INFRARED) | - (1 << HFLIP) | +[SENSOR_MI0360B] = (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), -[SENSOR_MO4000] = (1 << INFRARED) | - (1 << HFLIP) | +[SENSOR_MO4000] = (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), @@ -315,40 +309,32 @@ static const __u32 ctrl_dis[] = { (1 << VFLIP) | (1 << FREQ), -[SENSOR_OM6802] = (1 << INFRARED) | - (1 << HFLIP) | +[SENSOR_OM6802] = (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), -[SENSOR_OV7630] = (1 << INFRARED) | - (1 << HFLIP), +[SENSOR_OV7630] = (1 << HFLIP), -[SENSOR_OV7648] = (1 << INFRARED) | - (1 << HFLIP), +[SENSOR_OV7648] = (1 << HFLIP), [SENSOR_OV7660] = (1 << AUTOGAIN) | - (1 << INFRARED) | (1 << HFLIP) | (1 << VFLIP), [SENSOR_PO1030] = (1 << AUTOGAIN) | - (1 << INFRARED) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_PO2030N] = (1 << AUTOGAIN) | - (1 << INFRARED) | (1 << FREQ), [SENSOR_SOI768] = (1 << AUTOGAIN) | - (1 << INFRARED) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), [SENSOR_SP80708] = (1 << AUTOGAIN) | - (1 << INFRARED) | (1 << HFLIP) | (1 << VFLIP) | (1 << FREQ), @@ -1822,44 +1808,46 @@ static int sd_init(struct gspca_dev *gspca_dev) PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); switch (sd->bridge) { case BRIDGE_SN9C102P: + case BRIDGE_SN9C105: if (regF1 != 0x11) return -ENODEV; + break; + default: +/* case BRIDGE_SN9C110: */ +/* case BRIDGE_SN9C120: */ + if (regF1 != 0x12) + return -ENODEV; + } + + switch (sd->sensor) { + case SENSOR_MI0360: + mi0360_probe(gspca_dev); + break; + case SENSOR_OV7630: + ov7630_probe(gspca_dev); + break; + case SENSOR_OV7648: + ov7648_probe(gspca_dev); + break; + case SENSOR_PO2030N: + po2030n_probe(gspca_dev); + break; + } + + switch (sd->bridge) { + case BRIDGE_SN9C102P: reg_w1(gspca_dev, 0x02, regGpio[1]); break; case BRIDGE_SN9C105: - if (regF1 != 0x11) - return -ENODEV; - if (sd->sensor == SENSOR_MI0360) - mi0360_probe(gspca_dev); reg_w(gspca_dev, 0x01, regGpio, 2); break; + case BRIDGE_SN9C110: + reg_w1(gspca_dev, 0x02, 0x62); + break; case BRIDGE_SN9C120: - if (regF1 != 0x12) - return -ENODEV; - switch (sd->sensor) { - case SENSOR_MI0360: - mi0360_probe(gspca_dev); - break; - case SENSOR_OV7630: - ov7630_probe(gspca_dev); - break; - case SENSOR_OV7648: - ov7648_probe(gspca_dev); - break; - case SENSOR_PO2030N: - po2030n_probe(gspca_dev); - break; - } regGpio[1] = 0x70; /* no audio */ reg_w(gspca_dev, 0x01, regGpio, 2); break; - default: -/* case BRIDGE_SN9C110: */ -/* case BRIDGE_SN9C325: */ - if (regF1 != 0x12) - return -ENODEV; - reg_w1(gspca_dev, 0x02, 0x62); - break; } if (sd->sensor == SENSOR_OM6802) @@ -1874,6 +1862,8 @@ static int sd_init(struct gspca_dev *gspca_dev) sd->i2c_addr = sn9c1xx[9]; gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; + if (!(sd->flags & F_ILLUM)) + gspca_dev->ctrl_dis |= (1 << ILLUM); return gspca_dev->usb_err; } @@ -2197,16 +2187,28 @@ static void setsharpness(struct gspca_dev *gspca_dev) reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val); } -static void setinfrared(struct gspca_dev *gspca_dev) +static void setillum(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (gspca_dev->ctrl_dis & (1 << INFRARED)) + if (gspca_dev->ctrl_dis & (1 << ILLUM)) return; -/*fixme: different sequence for StarCam Clip and StarCam 370i */ -/* Clip */ - i2c_w1(gspca_dev, 0x02, /* gpio */ - sd->ctrls[INFRARED].val ? 0x66 : 0x64); + switch (sd->sensor) { + case SENSOR_ADCM1700: + reg_w1(gspca_dev, 0x02, /* gpio */ + sd->ctrls[ILLUM].val ? 0x64 : 0x60); + break; + case SENSOR_MT9V111: + if (starcam) + reg_w1(gspca_dev, 0x02, + sd->ctrls[ILLUM].val ? + 0x55 : 0x54); /* 370i */ + else + reg_w1(gspca_dev, 0x02, + sd->ctrls[ILLUM].val ? + 0x66 : 0x64); /* Clip */ + break; + } } static void setfreq(struct gspca_dev *gspca_dev) @@ -2344,7 +2346,7 @@ static int sd_start(struct gspca_dev *gspca_dev) /* sensor clock already enabled in sd_init */ /* reg_w1(gspca_dev, 0xf1, 0x00); */ reg01 = sn9c1xx[1]; - if (sd->flags & PDN_INV) + if (sd->flags & F_PDN_INV) reg01 ^= S_PDN_INV; /* power down inverted */ reg_w1(gspca_dev, 0x01, reg01); @@ -2907,13 +2909,11 @@ static const struct sd_desc sd_desc = { .driver_info = (BRIDGE_ ## bridge << 16) \ | (SENSOR_ ## sensor << 8) \ | (flags) -static const __devinitdata struct usb_device_id device_table[] = { -#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, -#endif - {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)}, - {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)}, + {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)}, + {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)}, {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)}, {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)}, {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)}, @@ -2925,7 +2925,7 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */ {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)}, /* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */ - {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)}, + {USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)}, /* or MT9V111 */ /* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */ /* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */ @@ -2936,10 +2936,8 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */ /* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */ {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)}, -#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)}, {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)}, -#endif {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/ {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/ /* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */ @@ -2962,16 +2960,15 @@ static const __devinitdata struct usb_device_id device_table[] = { /* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */ {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)}, {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)}, -#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)}, -#endif {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)}, {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)}, {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/ /* or GC0305 / GC0307 */ {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/ {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/ - {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/ + {USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)}, +/* {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */ /*sn9c120b*/ {} }; MODULE_DEVICE_TABLE(usb, device_table); @@ -3007,3 +3004,7 @@ static void __exit sd_mod_exit(void) module_init(sd_mod_init); module_exit(sd_mod_exit); + +module_param(starcam, int, 0644); +MODULE_PARM_DESC(starcam, + "StarCam model. 0: Clip, 1: 370i"); diff --git a/drivers/media/video/gspca/spca1528.c b/drivers/media/video/gspca/spca1528.c index e643386..76c006b 100644 --- a/drivers/media/video/gspca/spca1528.c +++ b/drivers/media/video/gspca/spca1528.c @@ -555,7 +555,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x04fc, 0x1528)}, {} }; diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 8e202b9..45552c3 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -1051,7 +1051,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200}, {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300}, {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler}, diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index 642839a..f7ef282 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -2155,7 +2155,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325}, {USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera}, {USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite}, diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index bc9dd90..e5bf865 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -786,7 +786,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra}, {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro}, /*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 7307638..3483193 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -1509,7 +1509,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam}, {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista}, {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110}, diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 3a162c6..e836e77 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -1061,7 +1061,7 @@ static const struct sd_desc *sd_desc[2] = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A}, {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A}, {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A}, diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c index 4040677..2e9c061 100644 --- a/drivers/media/video/gspca/sq905.c +++ b/drivers/media/video/gspca/sq905.c @@ -396,7 +396,7 @@ static int sd_start(struct gspca_dev *gspca_dev) } /* Table of supported USB devices */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x2770, 0x9120)}, {} }; diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c index 8ba1995..457563b 100644 --- a/drivers/media/video/gspca/sq905c.c +++ b/drivers/media/video/gspca/sq905c.c @@ -298,7 +298,7 @@ static int sd_start(struct gspca_dev *gspca_dev) } /* Table of supported USB devices */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x2770, 0x905c)}, {USB_DEVICE(0x2770, 0x9050)}, {USB_DEVICE(0x2770, 0x9051)}, diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c index a4a9881..8215d5d 100644 --- a/drivers/media/video/gspca/sq930x.c +++ b/drivers/media/video/gspca/sq930x.c @@ -1163,7 +1163,7 @@ static const struct sd_desc sd_desc = { #define ST(sensor, type) \ .driver_info = (SENSOR_ ## sensor << 8) \ | (type) -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)}, {USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)}, {USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)}, diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 11a192b..87be52b 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -495,7 +495,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x05e1, 0x0893)}, {} }; diff --git a/drivers/media/video/gspca/stv0680.c b/drivers/media/video/gspca/stv0680.c index b199ad4..e2ef41c 100644 --- a/drivers/media/video/gspca/stv0680.c +++ b/drivers/media/video/gspca/stv0680.c @@ -327,7 +327,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x0553, 0x0202)}, {USB_DEVICE(0x041e, 0x4007)}, {} diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c index 28ea417..7e06614 100644 --- a/drivers/media/video/gspca/stv06xx/stv06xx.c +++ b/drivers/media/video/gspca/stv06xx/stv06xx.c @@ -564,7 +564,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { /* QuickCam Express */ {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, /* LEGO cam / QuickCam Web */ diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index a9cbcd6..543542a 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -1162,7 +1162,7 @@ static const struct sd_desc sd_desc = { #define BS(bridge, subtype) \ .driver_info = (BRIDGE_ ## bridge << 8) \ | (subtype) -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)}, {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)}, {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)}, diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 8f0c331..a3eccd8 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -1416,7 +1416,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x17a1, 0x0128)}, {} }; diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index 38c22f0..933ef2c 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -388,7 +388,7 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x0920)}, {USB_DEVICE(0x046d, 0x0921)}, {USB_DEVICE(0x0545, 0x808b)}, diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 9b2ae1b..6caed73 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -4192,7 +4192,7 @@ static const struct sd_desc sd_desc = { #define BF(bridge, flags) \ .driver_info = (BRIDGE_ ## bridge << 8) \ | (flags) -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)}, {USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)}, {USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)}, diff --git a/drivers/media/video/gspca/xirlink_cit.c b/drivers/media/video/gspca/xirlink_cit.c index 5b5039a..c089a0f 100644 --- a/drivers/media/video/gspca/xirlink_cit.c +++ b/drivers/media/video/gspca/xirlink_cit.c @@ -3270,7 +3270,7 @@ static const struct sd_desc sd_desc_isoc_nego = { }; /* -- module initialisation -- */ -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { { USB_DEVICE_VER(0x0545, 0x8080, 0x0001, 0x0001), .driver_info = CIT_MODEL0 }, { USB_DEVICE_VER(0x0545, 0x8080, 0x0002, 0x0002), .driver_info = CIT_MODEL1 }, { USB_DEVICE_VER(0x0545, 0x8080, 0x030a, 0x030a), .driver_info = CIT_MODEL2 }, diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 14b85d4..865216e 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -6909,7 +6909,7 @@ static const struct sd_desc sd_desc = { #endif }; -static const __devinitdata struct usb_device_id device_table[] = { +static const struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x041e)}, {USB_DEVICE(0x041e, 0x4017)}, {USB_DEVICE(0x041e, 0x401c), .driver_info = SENSOR_PAS106}, diff --git a/drivers/media/video/hdpvr/Makefile b/drivers/media/video/hdpvr/Makefile index e0230fc..3baa9f6 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 f7d1ee5..a6572e5 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 24966aa..89b71fa 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 <linux/i2c.h> #include <linux/slab.h> @@ -28,106 +30,78 @@ #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; - } + 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; - return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ? - -1 : 0; -} + c = i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info); -int hdpvr_register_i2c_ir(struct hdpvr_device *dev) -{ - int i; - int ret = 0; - - 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); - 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, - 0x100|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; } -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); - 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, - 0x100|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) + if ((ret == 2) && (dev->i2c_buf[1] == (len - 1))) ret = 0; else if (ret >= 0) ret = -EIO; -error: - kfree(buf); return ret; } @@ -146,10 +120,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 +142,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; - - 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; + hdpvr_activate_ir(dev); - i2c_set_adapdata(i2c_adap, dev); + memcpy(&dev->i2c_adapter, &hdpvr_i2c_adapter_template, + sizeof(struct i2c_adapter)); + dev->i2c_adapter.dev.parent = &dev->udev->dev; - retval = i2c_add_adapter(i2c_adap); + i2c_set_adapdata(&dev->i2c_adapter, dev); - if (!retval) - dev->i2c_adapter = i2c_adap; - else - kfree(i2c_adap); + retval = i2c_add_adapter(&dev->i2c_adapter); -error: return retval; } + +#endif diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index d38fe10..514aea7 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 37f1e4c..ee74e3b 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 @@ -106,9 +107,11 @@ 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; + /* 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; diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index c87b6bc..d2b20ad 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -244,15 +244,17 @@ static void ir_key_poll(struct IR_i2c *ir) static u32 ir_key, ir_raw; int rc; - dprintk(2,"ir_poll_key\n"); + dprintk(3, "%s\n", __func__); rc = ir->get_key(ir, &ir_key, &ir_raw); if (rc < 0) { dprintk(2,"error\n"); return; } - if (rc) + if (rc) { + dprintk(1, "%s: keycode = 0x%04x\n", __func__, ir_key); rc_keydown(ir->rc, ir_key, 0); + } } static void ir_work(struct work_struct *work) @@ -321,6 +323,12 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) rc_type = RC_TYPE_OTHER; ir_codes = RC_MAP_AVERMEDIA_CARDBUS; break; + case 0x71: + name = "Hauppauge/Zilog Z8"; + ir->get_key = get_key_haup_xvr; + rc_type = RC_TYPE_RC5; + ir_codes = hauppauge ? RC_MAP_HAUPPAUGE_NEW : RC_MAP_RC5_TV; + break; } /* Let the caller override settings */ diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index e103b8f..9fb86a0 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -300,10 +300,15 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx) adap, type, 0, I2C_ADDRS(hw_addrs[idx])); } else if (hw == IVTV_HW_CX25840) { struct cx25840_platform_data pdata; + struct i2c_board_info cx25840_info = { + .type = "cx25840", + .addr = hw_addrs[idx], + .platform_data = &pdata, + }; pdata.pvr150_workaround = itv->pvr150_workaround; - sd = v4l2_i2c_new_subdev_cfg(&itv->v4l2_dev, - adap, type, 0, &pdata, hw_addrs[idx], NULL); + sd = v4l2_i2c_new_subdev_board(&itv->v4l2_dev, adap, + &cx25840_info, NULL); } else { sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, adap, type, hw_addrs[idx], NULL); diff --git a/drivers/media/video/mt9v011.c b/drivers/media/video/mt9v011.c index 209ff97..4904d25 100644 --- a/drivers/media/video/mt9v011.c +++ b/drivers/media/video/mt9v011.c @@ -12,17 +12,41 @@ #include <asm/div64.h> #include <media/v4l2-device.h> #include <media/v4l2-chip-ident.h> -#include "mt9v011.h" +#include <media/mt9v011.h> MODULE_DESCRIPTION("Micron mt9v011 sensor driver"); MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); MODULE_LICENSE("GPL"); - static int debug; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-2)"); +#define R00_MT9V011_CHIP_VERSION 0x00 +#define R01_MT9V011_ROWSTART 0x01 +#define R02_MT9V011_COLSTART 0x02 +#define R03_MT9V011_HEIGHT 0x03 +#define R04_MT9V011_WIDTH 0x04 +#define R05_MT9V011_HBLANK 0x05 +#define R06_MT9V011_VBLANK 0x06 +#define R07_MT9V011_OUT_CTRL 0x07 +#define R09_MT9V011_SHUTTER_WIDTH 0x09 +#define R0A_MT9V011_CLK_SPEED 0x0a +#define R0B_MT9V011_RESTART 0x0b +#define R0C_MT9V011_SHUTTER_DELAY 0x0c +#define R0D_MT9V011_RESET 0x0d +#define R1E_MT9V011_DIGITAL_ZOOM 0x1e +#define R20_MT9V011_READ_MODE 0x20 +#define R2B_MT9V011_GREEN_1_GAIN 0x2b +#define R2C_MT9V011_BLUE_GAIN 0x2c +#define R2D_MT9V011_RED_GAIN 0x2d +#define R2E_MT9V011_GREEN_2_GAIN 0x2e +#define R35_MT9V011_GLOBAL_GAIN 0x35 +#define RF1_MT9V011_CHIP_ENABLE 0xf1 + +#define MT9V011_VERSION 0x8232 +#define MT9V011_REV_B_VERSION 0x8243 + /* supported controls */ static struct v4l2_queryctrl mt9v011_qctrl[] = { { @@ -469,23 +493,6 @@ static int mt9v011_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt return 0; } -static int mt9v011_s_config(struct v4l2_subdev *sd, int dumb, void *data) -{ - struct mt9v011 *core = to_mt9v011(sd); - unsigned *xtal = data; - - v4l2_dbg(1, debug, sd, "s_config called\n"); - - if (xtal) { - core->xtal = *xtal; - v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n", - *xtal / 1000000, (*xtal / 1000) % 1000); - } - - return 0; -} - - #ifdef CONFIG_VIDEO_ADV_DEBUG static int mt9v011_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) @@ -536,7 +543,6 @@ static const struct v4l2_subdev_core_ops mt9v011_core_ops = { .g_ctrl = mt9v011_g_ctrl, .s_ctrl = mt9v011_s_ctrl, .reset = mt9v011_reset, - .s_config = mt9v011_s_config, .g_chip_ident = mt9v011_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = mt9v011_g_register, @@ -596,6 +602,14 @@ static int mt9v011_probe(struct i2c_client *c, core->height = 480; core->xtal = 27000000; /* Hz */ + if (c->dev.platform_data) { + struct mt9v011_platform_data *pdata = c->dev.platform_data; + + core->xtal = pdata->xtal; + v4l2_dbg(1, debug, sd, "xtal set to %d.%03d MHz\n", + core->xtal / 1000000, (core->xtal / 1000) % 1000); + } + v4l_info(c, "chip found @ 0x%02x (%s - chip version 0x%04x)\n", c->addr << 1, c->adapter->name, version); diff --git a/drivers/media/video/mt9v011.h b/drivers/media/video/mt9v011.h deleted file mode 100644 index 3350fd6..0000000 --- a/drivers/media/video/mt9v011.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor - * - * Copyright (c) 2009 Mauro Carvalho Chehab (mchehab@redhat.com) - * This code is placed under the terms of the GNU General Public License v2 - */ - -#ifndef MT9V011_H_ -#define MT9V011_H_ - -#define R00_MT9V011_CHIP_VERSION 0x00 -#define R01_MT9V011_ROWSTART 0x01 -#define R02_MT9V011_COLSTART 0x02 -#define R03_MT9V011_HEIGHT 0x03 -#define R04_MT9V011_WIDTH 0x04 -#define R05_MT9V011_HBLANK 0x05 -#define R06_MT9V011_VBLANK 0x06 -#define R07_MT9V011_OUT_CTRL 0x07 -#define R09_MT9V011_SHUTTER_WIDTH 0x09 -#define R0A_MT9V011_CLK_SPEED 0x0a -#define R0B_MT9V011_RESTART 0x0b -#define R0C_MT9V011_SHUTTER_DELAY 0x0c -#define R0D_MT9V011_RESET 0x0d -#define R1E_MT9V011_DIGITAL_ZOOM 0x1e -#define R20_MT9V011_READ_MODE 0x20 -#define R2B_MT9V011_GREEN_1_GAIN 0x2b -#define R2C_MT9V011_BLUE_GAIN 0x2c -#define R2D_MT9V011_RED_GAIN 0x2d -#define R2E_MT9V011_GREEN_2_GAIN 0x2e -#define R35_MT9V011_GLOBAL_GAIN 0x35 -#define RF1_MT9V011_CHIP_ENABLE 0xf1 - -#define MT9V011_VERSION 0x8232 -#define MT9V011_REV_B_VERSION 0x8243 - -#endif diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index c881a64..d4e7c11 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -1449,47 +1449,6 @@ static int ov7670_g_chip_ident(struct v4l2_subdev *sd, return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0); } -static int ov7670_s_config(struct v4l2_subdev *sd, int dumb, void *data) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct ov7670_config *config = data; - struct ov7670_info *info = to_state(sd); - int ret; - - info->clock_speed = 30; /* default: a guess */ - - /* - * Must apply configuration before initializing device, because it - * selects I/O method. - */ - if (config) { - info->min_width = config->min_width; - info->min_height = config->min_height; - info->use_smbus = config->use_smbus; - - if (config->clock_speed) - info->clock_speed = config->clock_speed; - } - - /* Make sure it's an ov7670 */ - ret = ov7670_detect(sd); - if (ret) { - v4l_dbg(1, debug, client, - "chip found @ 0x%x (%s) is not an ov7670 chip.\n", - client->addr << 1, client->adapter->name); - kfree(info); - return ret; - } - v4l_info(client, "chip found @ 0x%02x (%s)\n", - client->addr << 1, client->adapter->name); - - info->fmt = &ov7670_formats[0]; - info->sat = 128; /* Review this */ - info->clkrc = info->clock_speed / 30; - - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) { @@ -1528,7 +1487,6 @@ static const struct v4l2_subdev_core_ops ov7670_core_ops = { .s_ctrl = ov7670_s_ctrl, .queryctrl = ov7670_queryctrl, .reset = ov7670_reset, - .s_config = ov7670_s_config, .init = ov7670_init, #ifdef CONFIG_VIDEO_ADV_DEBUG .g_register = ov7670_g_register, @@ -1558,6 +1516,7 @@ static int ov7670_probe(struct i2c_client *client, { struct v4l2_subdev *sd; struct ov7670_info *info; + int ret; info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL); if (info == NULL) @@ -1565,6 +1524,37 @@ static int ov7670_probe(struct i2c_client *client, sd = &info->sd; v4l2_i2c_subdev_init(sd, client, &ov7670_ops); + info->clock_speed = 30; /* default: a guess */ + if (client->dev.platform_data) { + struct ov7670_config *config = client->dev.platform_data; + + /* + * Must apply configuration before initializing device, because it + * selects I/O method. + */ + info->min_width = config->min_width; + info->min_height = config->min_height; + info->use_smbus = config->use_smbus; + + if (config->clock_speed) + info->clock_speed = config->clock_speed; + } + + /* Make sure it's an ov7670 */ + ret = ov7670_detect(sd); + if (ret) { + v4l_dbg(1, debug, client, + "chip found @ 0x%x (%s) is not an ov7670 chip.\n", + client->addr << 1, client->adapter->name); + kfree(info); + return ret; + } + v4l_info(client, "chip found @ 0x%02x (%s)\n", + client->addr << 1, client->adapter->name); + + info->fmt = &ov7670_formats[0]; + info->sat = 128; /* Review this */ + info->clkrc = info->clock_speed / 30; return 0; } diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index ac94a8b..305e6aa 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -40,6 +40,7 @@ #include "pvrusb2-io.h" #include <media/v4l2-device.h> #include <media/cx2341x.h> +#include <media/ir-kbd-i2c.h> #include "pvrusb2-devattr.h" /* Legal values for PVR2_CID_HSM */ @@ -202,6 +203,7 @@ struct pvr2_hdw { /* IR related */ unsigned int ir_scheme_active; /* IR scheme as seen from the outside */ + struct IR_i2c_init_data ir_init_data; /* params passed to IR modules */ /* Frequency table */ unsigned int freqTable[FREQTABLE_SIZE]; diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 7cbe18c..ccc8849 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -19,6 +19,7 @@ */ #include <linux/i2c.h> +#include <media/ir-kbd-i2c.h> #include "pvrusb2-i2c-core.h" #include "pvrusb2-hdw-internal.h" #include "pvrusb2-debug.h" @@ -48,13 +49,6 @@ module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video, MODULE_PARM_DESC(disable_autoload_ir_video, "1=do not try to autoload ir_video IR receiver"); -/* Mapping of IR schemes to known I2C addresses - if any */ -static const unsigned char ir_video_addresses[] = { - [PVR2_IR_SCHEME_ZILOG] = 0x71, - [PVR2_IR_SCHEME_29XXX] = 0x18, - [PVR2_IR_SCHEME_24XXX] = 0x18, -}; - static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ u8 i2c_addr, /* I2C address we're talking to */ u8 *data, /* Data to write */ @@ -574,26 +568,56 @@ static void do_i2c_scan(struct pvr2_hdw *hdw) static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw) { struct i2c_board_info info; - unsigned char addr = 0; + struct IR_i2c_init_data *init_data = &hdw->ir_init_data; if (pvr2_disable_ir_video) { pvr2_trace(PVR2_TRACE_INFO, "Automatic binding of ir_video has been disabled."); return; } - if (hdw->ir_scheme_active < ARRAY_SIZE(ir_video_addresses)) { - addr = ir_video_addresses[hdw->ir_scheme_active]; - } - if (!addr) { + memset(&info, 0, sizeof(struct i2c_board_info)); + switch (hdw->ir_scheme_active) { + case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */ + case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */ + init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; + init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; + init_data->type = RC_TYPE_RC5; + init_data->name = hdw->hdw_desc->description; + init_data->polling_interval = 100; /* ms From ir-kbd-i2c */ + /* IR Receiver */ + info.addr = 0x18; + info.platform_data = init_data; + strlcpy(info.type, "ir_video", I2C_NAME_SIZE); + pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.", + info.type, info.addr); + i2c_new_device(&hdw->i2c_adap, &info); + break; + case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */ + case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */ + 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 = hdw->hdw_desc->description; + init_data->polling_interval = 260; /* ms From lirc_zilog */ + /* IR Receiver */ + info.addr = 0x71; + info.platform_data = init_data; + strlcpy(info.type, "ir_rx_z8f0811_haup", I2C_NAME_SIZE); + pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.", + info.type, info.addr); + i2c_new_device(&hdw->i2c_adap, &info); + /* IR Trasmitter */ + info.addr = 0x70; + info.platform_data = init_data; + strlcpy(info.type, "ir_tx_z8f0811_haup", I2C_NAME_SIZE); + pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.", + info.type, info.addr); + i2c_new_device(&hdw->i2c_adap, &info); + break; + default: /* The device either doesn't support I2C-based IR or we don't know (yet) how to operate IR on the device. */ - return; + break; } - pvr2_trace(PVR2_TRACE_INFO, - "Binding ir_video to i2c address 0x%02x.", addr); - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - info.addr = addr; - i2c_new_device(&hdw->i2c_adap, &info); } void pvr2_i2c_core_init(struct pvr2_hdw *hdw) diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index e7aa588..deb8fcf 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5179,18 +5179,8 @@ struct saa7134_board saa7134_boards[] = { [SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG] = { .name = "Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid", .audio_clock = 0x00187de7, -#if 0 - /* - * FIXME: Analog mode doesn't work, if digital is enabled. The proper - * fix is to use tda8290 driver, but Kworld seems to use an - * unsupported version of tda8295. - */ - .tuner_type = TUNER_NXP_TDA18271, /* TUNER_PHILIPS_TDA8290 */ - .tuner_addr = 0x60, -#else - .tuner_type = UNSET, + .tuner_type = TUNER_PHILIPS_TDA8290, .tuner_addr = ADDR_UNSET, -#endif .radio_type = UNSET, .radio_addr = ADDR_UNSET, .gpiomask = 0x8e054000, @@ -6932,10 +6922,17 @@ static inline int saa7134_kworld_sbtvd_toggle_agc(struct saa7134_dev *dev, /* toggle AGC switch through GPIO 27 */ switch (mode) { case TDA18271_ANALOG: - saa7134_set_gpio(dev, 27, 0); + saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000); + saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000); + msleep(20); break; case TDA18271_DIGITAL: - saa7134_set_gpio(dev, 27, 1); + saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000); + saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000); + msleep(20); + saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000); + saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000); + msleep(30); break; default: return -EINVAL; @@ -6993,6 +6990,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev, int saa7134_tuner_callback(void *priv, int component, int command, int arg) { struct saa7134_dev *dev = priv; + if (dev != NULL) { switch (dev->tuner_type) { case TUNER_PHILIPS_TDA8290: @@ -7659,36 +7657,11 @@ int saa7134_board_init2(struct saa7134_dev *dev) break; } case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: - { - struct i2c_msg msg = { .addr = 0x4b, .flags = 0 }; - int i; - static u8 buffer[][2] = { - {0x30, 0x31}, - {0xff, 0x00}, - {0x41, 0x03}, - {0x41, 0x1a}, - {0xff, 0x02}, - {0x34, 0x00}, - {0x45, 0x97}, - {0x45, 0xc1}, - }; saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000); saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000); - /* - * FIXME: identify what device is at addr 0x4b and what means - * this initialization - */ - for (i = 0; i < ARRAY_SIZE(buffer); i++) { - msg.buf = &buffer[i][0]; - msg.len = ARRAY_SIZE(buffer[0]); - if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) - printk(KERN_WARNING - "%s: Unable to enable tuner(%i).\n", - dev->name, i); - } + saa7134_set_gpio(dev, 27, 0); break; - } } /* switch() */ /* initialize tuner */ diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 3315a48..f65cad2 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -237,12 +237,39 @@ static struct tda18271_std_map mb86a20s_tda18271_std_map = { static struct tda18271_config kworld_tda18271_config = { .std_map = &mb86a20s_tda18271_std_map, .gate = TDA18271_GATE_DIGITAL, + .config = 3, /* Use tuner callback for AGC */ + }; static const struct mb86a20s_config kworld_mb86a20s_config = { .demod_address = 0x10, }; +static int kworld_sbtvd_gate_ctrl(struct dvb_frontend* fe, int enable) +{ + struct saa7134_dev *dev = fe->dvb->priv; + + unsigned char initmsg[] = {0x45, 0x97}; + unsigned char msg_enable[] = {0x45, 0xc1}; + unsigned char msg_disable[] = {0x45, 0x81}; + struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = initmsg, .len = 2}; + + if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { + wprintk("could not access the I2C gate\n"); + return -EIO; + } + if (enable) + msg.buf = msg_enable; + else + msg.buf = msg_disable; + if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { + wprintk("could not access the I2C gate\n"); + return -EIO; + } + msleep(20); + return 0; +} + /* ================================================================== * tda1004x based DVB-T cards, helper functions */ @@ -623,37 +650,6 @@ static struct tda827x_config tda827x_cfg_2_sw42 = { /* ------------------------------------------------------------------ */ -static int __kworld_sbtvd_i2c_gate_ctrl(struct saa7134_dev *dev, int enable) -{ - unsigned char initmsg[] = {0x45, 0x97}; - unsigned char msg_enable[] = {0x45, 0xc1}; - unsigned char msg_disable[] = {0x45, 0x81}; - struct i2c_msg msg = {.addr = 0x4b, .flags = 0, .buf = initmsg, .len = 2}; - - if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { - wprintk("could not access the I2C gate\n"); - return -EIO; - } - if (enable) - msg.buf = msg_enable; - else - msg.buf = msg_disable; - if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) { - wprintk("could not access the I2C gate\n"); - return -EIO; - } - msleep(20); - return 0; -} -static int kworld_sbtvd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct saa7134_dev *dev = fe->dvb->priv; - - return __kworld_sbtvd_i2c_gate_ctrl(dev, enable); -} - -/* ------------------------------------------------------------------ */ - static struct tda1004x_config tda827x_lifeview_config = { .demod_address = 0x08, .invert = 1, @@ -1660,27 +1656,23 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: - __kworld_sbtvd_i2c_gate_ctrl(dev, 0); - saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000); - saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000); - msleep(20); - saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000); - saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000); - msleep(20); + /* Switch to digital mode */ + saa7134_tuner_callback(dev, 0, + TDA18271_CALLBACK_CMD_AGC_ENABLE, 1); fe0->dvb.frontend = dvb_attach(mb86a20s_attach, &kworld_mb86a20s_config, &dev->i2c_adap); - __kworld_sbtvd_i2c_gate_ctrl(dev, 1); if (fe0->dvb.frontend != NULL) { + dvb_attach(tda829x_attach, fe0->dvb.frontend, + &dev->i2c_adap, 0x4b, + &tda829x_no_probe); dvb_attach(tda18271_attach, fe0->dvb.frontend, 0x60, &dev->i2c_adap, &kworld_tda18271_config); - /* - * Only after success, it can initialize the gate, otherwise - * an OOPS will hit, due to kfree(fe0->dvb.frontend) - */ - fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_i2c_gate_ctrl; + fe0->dvb.frontend->ops.i2c_gate_ctrl = kworld_sbtvd_gate_ctrl; } + + /* mb86a20s need to use the I2C gateway */ break; default: wprintk("Huh? unknown DVB card?\n"); diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h index 41064c7..b3d2cc7 100644 --- a/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/drivers/media/video/sn9c102/sn9c102_devtable.h @@ -47,8 +47,8 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, /* { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, OV6650 */ -#endif { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), }, +#endif { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x6025, BRIDGE_SN9C102), }, #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE @@ -56,78 +56,68 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x6029, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x602a, BRIDGE_SN9C102), }, #endif - { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, + { SN9C102_USB_DEVICE(0x0c45, 0x602b, BRIDGE_SN9C102), }, /* not in sonixb */ #if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x602c, BRIDGE_SN9C102), }, /* { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, HV7131R */ { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, #endif - { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, + { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, /* not in sonixb */ /* SN9C103 */ - { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), }, +/* { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, non existent ? */ + { SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), }, /* not in sonixb */ +#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE /* { SN9C102_USB_DEVICE(0x0c45, 0x6083, BRIDGE_SN9C103), }, HY7131D/E */ - { SN9C102_USB_DEVICE(0x0c45, 0x6088, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x608a, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), }, +/* { SN9C102_USB_DEVICE(0x0c45, 0x6088, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x608a, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x608b, BRIDGE_SN9C103), }, non existent ? */ { SN9C102_USB_DEVICE(0x0c45, 0x608c, BRIDGE_SN9C103), }, /* { SN9C102_USB_DEVICE(0x0c45, 0x608e, BRIDGE_SN9C103), }, CISVF10 */ -#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x608f, BRIDGE_SN9C103), }, -#endif - { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), }, +/* { SN9C102_USB_DEVICE(0x0c45, 0x60a0, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60a2, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60a3, BRIDGE_SN9C103), }, non existent ? */ /* { SN9C102_USB_DEVICE(0x0c45, 0x60a8, BRIDGE_SN9C103), }, PAS106 */ /* { SN9C102_USB_DEVICE(0x0c45, 0x60aa, BRIDGE_SN9C103), }, TAS5130 */ -/* { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, TAS5130 */ - { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, +/* { SN9C102_USB_DEVICE(0x0c45, 0x60ab, BRIDGE_SN9C103), }, TAS5110, non existent */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60ac, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60ae, BRIDGE_SN9C103), }, non existent ? */ { SN9C102_USB_DEVICE(0x0c45, 0x60af, BRIDGE_SN9C103), }, -#if !defined CONFIG_USB_GSPCA_SONIXB && !defined CONFIG_USB_GSPCA_SONIXB_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x60b0, BRIDGE_SN9C103), }, +/* { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60ba, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60bb, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), }, non existent ? */ #endif - { SN9C102_USB_DEVICE(0x0c45, 0x60b2, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60b3, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60b8, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60ba, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60bb, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60bc, BRIDGE_SN9C103), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60be, BRIDGE_SN9C103), }, /* SN9C105 */ #if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE { SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), }, -#endif { SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), }, - { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), }, +/* { SN9C102_USB_DEVICE(0x0c45, 0x60c2, BRIDGE_SN9C105), }, PO1030 */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60c8, BRIDGE_SN9C105), }, OM6801 */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60cc, BRIDGE_SN9C105), }, HV7131GP */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60ea, BRIDGE_SN9C105), }, non existent ? */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60ec, BRIDGE_SN9C105), }, MO4000 */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60ef, BRIDGE_SN9C105), }, ICM105C */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x60fa, BRIDGE_SN9C105), }, OV7648 */ { SN9C102_USB_DEVICE(0x0c45, 0x60fb, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x0c45, 0x60fc, BRIDGE_SN9C105), }, { SN9C102_USB_DEVICE(0x0c45, 0x60fe, BRIDGE_SN9C105), }, /* SN9C120 */ { SN9C102_USB_DEVICE(0x0458, 0x7025, BRIDGE_SN9C120), }, -#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE - { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, -#endif - { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, - { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, -#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE +/* { SN9C102_USB_DEVICE(0x0c45, 0x6102, BRIDGE_SN9C120), }, po2030 */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x6108, BRIDGE_SN9C120), }, om6801 */ +/* { SN9C102_USB_DEVICE(0x0c45, 0x610f, BRIDGE_SN9C120), }, S5K53BEB */ { SN9C102_USB_DEVICE(0x0c45, 0x6130, BRIDGE_SN9C120), }, -#endif /* { SN9C102_USB_DEVICE(0x0c45, 0x6138, BRIDGE_SN9C120), }, MO8000 */ -#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), }, -#endif { SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), }, -#if !defined CONFIG_USB_GSPCA_SONIXJ && !defined CONFIG_USB_GSPCA_SONIXJ_MODULE { SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), }, { SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), }, #endif diff --git a/drivers/media/video/sr030pc30.c b/drivers/media/video/sr030pc30.c index 864696b..c901721 100644 --- a/drivers/media/video/sr030pc30.c +++ b/drivers/media/video/sr030pc30.c @@ -714,15 +714,6 @@ static int sr030pc30_base_config(struct v4l2_subdev *sd) return ret; } -static int sr030pc30_s_config(struct v4l2_subdev *sd, - int irq, void *platform_data) -{ - struct sr030pc30_info *info = to_sr030pc30(sd); - - info->pdata = platform_data; - return 0; -} - static int sr030pc30_s_stream(struct v4l2_subdev *sd, int enable) { return 0; @@ -763,7 +754,6 @@ static int sr030pc30_s_power(struct v4l2_subdev *sd, int on) } static const struct v4l2_subdev_core_ops sr030pc30_core_ops = { - .s_config = sr030pc30_s_config, .s_power = sr030pc30_s_power, .queryctrl = sr030pc30_queryctrl, .s_ctrl = sr030pc30_s_ctrl, diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c deleted file mode 100644 index 35b6ff5..0000000 --- a/drivers/media/video/tda9875.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * For the TDA9875 chip - * (The TDA9875 is used on the Diamond DTV2000 french version - * Other cards probably use these chips as well.) - * This driver will not complain if used with any - * other i2c device with the same address. - * - * Copyright (c) 2000 Guillaume Delvit based on Gerd Knorr source and - * Eric Sandeen - * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org> - * This code is placed under the terms of the GNU General Public License - * Based on tda9855.c by Steve VanDeBogart (vandebo@uclink.berkeley.edu) - * Which was based on tda8425.c by Greg Alexander (c) 1998 - * - * OPTIONS: - * debug - set to 1 if you'd like to see debug messages - * - * Revision: 0.1 - original version - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/timer.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/videodev2.h> -#include <media/v4l2-device.h> -#include <media/i2c-addr.h> - -static int debug; /* insmod parameter */ -module_param(debug, int, S_IRUGO | S_IWUSR); -MODULE_LICENSE("GPL"); - - -/* This is a superset of the TDA9875 */ -struct tda9875 { - struct v4l2_subdev sd; - int rvol, lvol; - int bass, treble; -}; - -static inline struct tda9875 *to_state(struct v4l2_subdev *sd) -{ - return container_of(sd, struct tda9875, sd); -} - -#define dprintk if (debug) printk - -/* The TDA9875 is made by Philips Semiconductor - * http://www.semiconductors.philips.com - * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator - * - */ - - /* subaddresses for TDA9875 */ -#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/ -#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */ -#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/ -#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/ - -#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/ -#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/ -#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/ -#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/ - -#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/ -#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/ -#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/ -#define TDA9875_MVL 0x1a /* Main volume gauche */ -#define TDA9875_MVR 0x1b /* Main volume droite */ -#define TDA9875_MBA 0x1d /* Main Basse */ -#define TDA9875_MTR 0x1e /* Main treble */ -#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/ -#define TDA9875_AVL 0x20 /* Auxilary volume gauche */ -#define TDA9875_AVR 0x21 /* Auxilary volume droite */ -#define TDA9875_ABA 0x22 /* Auxilary Basse */ -#define TDA9875_ATR 0x23 /* Auxilary treble */ - -#define TDA9875_MSR 0x02 /* Monitor select register */ -#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */ -#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */ -#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */ -#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */ -#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */ -#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */ -#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/ -#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/ -#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/ - -/* values */ -#define TDA9875_MUTE_ON 0xff /* general mute */ -#define TDA9875_MUTE_OFF 0xcc /* general no mute */ - - - -/* Begin code */ - -static int tda9875_write(struct v4l2_subdev *sd, int subaddr, unsigned char val) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - unsigned char buffer[2]; - - v4l2_dbg(1, debug, sd, "Writing %d 0x%x\n", subaddr, val); - buffer[0] = subaddr; - buffer[1] = val; - if (2 != i2c_master_send(client, buffer, 2)) { - v4l2_warn(sd, "I/O error, trying (write %d 0x%x)\n", - subaddr, val); - return -1; - } - return 0; -} - - -static int i2c_read_register(struct i2c_client *client, int addr, int reg) -{ - unsigned char write[1]; - unsigned char read[1]; - struct i2c_msg msgs[2] = { - { addr, 0, 1, write }, - { addr, I2C_M_RD, 1, read } - }; - - write[0] = reg; - - if (2 != i2c_transfer(client->adapter, msgs, 2)) { - v4l_warn(client, "I/O error (read2)\n"); - return -1; - } - v4l_dbg(1, debug, client, "chip_read2: reg%d=0x%x\n", reg, read[0]); - return read[0]; -} - -static void tda9875_set(struct v4l2_subdev *sd) -{ - struct tda9875 *tda = to_state(sd); - unsigned char a; - - v4l2_dbg(1, debug, sd, "tda9875_set(%04x,%04x,%04x,%04x)\n", - tda->lvol, tda->rvol, tda->bass, tda->treble); - - a = tda->lvol & 0xff; - tda9875_write(sd, TDA9875_MVL, a); - a =tda->rvol & 0xff; - tda9875_write(sd, TDA9875_MVR, a); - a =tda->bass & 0xff; - tda9875_write(sd, TDA9875_MBA, a); - a =tda->treble & 0xff; - tda9875_write(sd, TDA9875_MTR, a); -} - -static void do_tda9875_init(struct v4l2_subdev *sd) -{ - struct tda9875 *t = to_state(sd); - - v4l2_dbg(1, debug, sd, "In tda9875_init\n"); - tda9875_write(sd, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/ - tda9875_write(sd, TDA9875_MSR, 0x03); /* Monitor 0b00000XXX*/ - tda9875_write(sd, TDA9875_C1MSB, 0x00); /*Car1(FM) MSB XMHz*/ - tda9875_write(sd, TDA9875_C1MIB, 0x00); /*Car1(FM) MIB XMHz*/ - tda9875_write(sd, TDA9875_C1LSB, 0x00); /*Car1(FM) LSB XMHz*/ - tda9875_write(sd, TDA9875_C2MSB, 0x00); /*Car2(NICAM) MSB XMHz*/ - tda9875_write(sd, TDA9875_C2MIB, 0x00); /*Car2(NICAM) MIB XMHz*/ - tda9875_write(sd, TDA9875_C2LSB, 0x00); /*Car2(NICAM) LSB XMHz*/ - tda9875_write(sd, TDA9875_DCR, 0x00); /*Demod config 0x00*/ - tda9875_write(sd, TDA9875_DEEM, 0x44); /*DE-Emph 0b0100 0100*/ - tda9875_write(sd, TDA9875_FMAT, 0x00); /*FM Matrix reg 0x00*/ - tda9875_write(sd, TDA9875_SC1, 0x00); /* SCART 1 (SC1)*/ - tda9875_write(sd, TDA9875_SC2, 0x01); /* SCART 2 (sc2)*/ - - tda9875_write(sd, TDA9875_CH1V, 0x10); /* Channel volume 1 mute*/ - tda9875_write(sd, TDA9875_CH2V, 0x10); /* Channel volume 2 mute */ - tda9875_write(sd, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/ - tda9875_write(sd, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/ - tda9875_write(sd, TDA9875_LOSR, 0x00); /* line out (in:mono)*/ - tda9875_write(sd, TDA9875_AER, 0x00); /*06 Effect (AVL+PSEUDO) */ - tda9875_write(sd, TDA9875_MCS, 0x44); /* Main ch select (DAC) */ - tda9875_write(sd, TDA9875_MVL, 0x03); /* Vol Main left 10dB */ - tda9875_write(sd, TDA9875_MVR, 0x03); /* Vol Main right 10dB*/ - tda9875_write(sd, TDA9875_MBA, 0x00); /* Main Bass Main 0dB*/ - tda9875_write(sd, TDA9875_MTR, 0x00); /* Main Treble Main 0dB*/ - tda9875_write(sd, TDA9875_ACS, 0x44); /* Aux chan select (dac)*/ - tda9875_write(sd, TDA9875_AVL, 0x00); /* Vol Aux left 0dB*/ - tda9875_write(sd, TDA9875_AVR, 0x00); /* Vol Aux right 0dB*/ - tda9875_write(sd, TDA9875_ABA, 0x00); /* Aux Bass Main 0dB*/ - tda9875_write(sd, TDA9875_ATR, 0x00); /* Aux Aigus Main 0dB*/ - - tda9875_write(sd, TDA9875_MUT, 0xcc); /* General mute */ - - t->lvol = t->rvol = 0; /* 0dB */ - t->bass = 0; /* 0dB */ - t->treble = 0; /* 0dB */ - tda9875_set(sd); -} - - -static int tda9875_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct tda9875 *t = to_state(sd); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - { - int left = (t->lvol+84)*606; - int right = (t->rvol+84)*606; - - ctrl->value=max(left,right); - return 0; - } - case V4L2_CID_AUDIO_BALANCE: - { - int left = (t->lvol+84)*606; - int right = (t->rvol+84)*606; - int volume = max(left,right); - int balance = (32768*min(left,right))/ - (volume ? volume : 1); - ctrl->value=(left<right)? - (65535-balance) : balance; - return 0; - } - case V4L2_CID_AUDIO_BASS: - ctrl->value = (t->bass+12)*2427; /* min -12 max +15 */ - return 0; - case V4L2_CID_AUDIO_TREBLE: - ctrl->value = (t->treble+12)*2730;/* min -12 max +12 */ - return 0; - } - return -EINVAL; -} - -static int tda9875_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) -{ - struct tda9875 *t = to_state(sd); - int chvol = 0, volume = 0, balance = 0, left, right; - - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - left = (t->lvol+84)*606; - right = (t->rvol+84)*606; - - volume = max(left,right); - balance = (32768*min(left,right))/ - (volume ? volume : 1); - balance =(left<right)? - (65535-balance) : balance; - - volume = ctrl->value; - - chvol=1; - break; - case V4L2_CID_AUDIO_BALANCE: - left = (t->lvol+84)*606; - right = (t->rvol+84)*606; - - volume=max(left,right); - - balance = ctrl->value; - - chvol=1; - break; - case V4L2_CID_AUDIO_BASS: - t->bass = ((ctrl->value/2400)-12) & 0xff; - if (t->bass > 15) - t->bass = 15; - if (t->bass < -12) - t->bass = -12 & 0xff; - break; - case V4L2_CID_AUDIO_TREBLE: - t->treble = ((ctrl->value/2700)-12) & 0xff; - if (t->treble > 12) - t->treble = 12; - if (t->treble < -12) - t->treble = -12 & 0xff; - break; - default: - return -EINVAL; - } - - if (chvol) { - left = (min(65536 - balance,32768) * - volume) / 32768; - right = (min(balance,32768) * - volume) / 32768; - t->lvol = ((left/606)-84) & 0xff; - if (t->lvol > 24) - t->lvol = 24; - if (t->lvol < -84) - t->lvol = -84 & 0xff; - - t->rvol = ((right/606)-84) & 0xff; - if (t->rvol > 24) - t->rvol = 24; - if (t->rvol < -84) - t->rvol = -84 & 0xff; - } - - tda9875_set(sd); - return 0; -} - -static int tda9875_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) -{ - switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880); - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768); - } - return -EINVAL; -} - -/* ----------------------------------------------------------------------- */ - -static const struct v4l2_subdev_core_ops tda9875_core_ops = { - .queryctrl = tda9875_queryctrl, - .g_ctrl = tda9875_g_ctrl, - .s_ctrl = tda9875_s_ctrl, -}; - -static const struct v4l2_subdev_ops tda9875_ops = { - .core = &tda9875_core_ops, -}; - -/* ----------------------------------------------------------------------- */ - - -/* *********************** * - * i2c interface functions * - * *********************** */ - -static int tda9875_checkit(struct i2c_client *client, int addr) -{ - int dic, rev; - - dic = i2c_read_register(client, addr, 254); - rev = i2c_read_register(client, addr, 255); - - if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */ - v4l_info(client, "tda9875%s rev. %d detected at 0x%02x\n", - dic == 0 ? "" : "A", rev, addr << 1); - return 1; - } - v4l_info(client, "no such chip at 0x%02x (dic=0x%x rev=0x%x)\n", - addr << 1, dic, rev); - return 0; -} - -static int tda9875_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct tda9875 *t; - struct v4l2_subdev *sd; - - v4l_info(client, "chip found @ 0x%02x (%s)\n", - client->addr << 1, client->adapter->name); - - if (!tda9875_checkit(client, client->addr)) - return -ENODEV; - - t = kzalloc(sizeof(*t), GFP_KERNEL); - if (!t) - return -ENOMEM; - sd = &t->sd; - v4l2_i2c_subdev_init(sd, client, &tda9875_ops); - - do_tda9875_init(sd); - return 0; -} - -static int tda9875_remove(struct i2c_client *client) -{ - struct v4l2_subdev *sd = i2c_get_clientdata(client); - - do_tda9875_init(sd); - v4l2_device_unregister_subdev(sd); - kfree(to_state(sd)); - return 0; -} - -static const struct i2c_device_id tda9875_id[] = { - { "tda9875", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, tda9875_id); - -static struct i2c_driver tda9875_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "tda9875", - }, - .probe = tda9875_probe, - .remove = tda9875_remove, - .id_table = tda9875_id, -}; - -static __init int init_tda9875(void) -{ - return i2c_add_driver(&tda9875_driver); -} - -static __exit void exit_tda9875(void) -{ - i2c_del_driver(&tda9875_driver); -} - -module_init(init_tda9875); -module_exit(exit_tda9875); diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c index a1ffe18..df33a1d 100644 --- a/drivers/media/video/tlg2300/pd-video.c +++ b/drivers/media/video/tlg2300/pd-video.c @@ -512,19 +512,20 @@ int alloc_bulk_urbs_generic(struct urb **urb_array, int num, int buf_size, gfp_t gfp_flags, usb_complete_t complete_fn, void *context) { - struct urb *urb; - void *mem; - int i; + int i = 0; - for (i = 0; i < num; i++) { - urb = usb_alloc_urb(0, gfp_flags); + for (; i < num; i++) { + void *mem; + struct urb *urb = usb_alloc_urb(0, gfp_flags); if (urb == NULL) return i; mem = usb_alloc_coherent(udev, buf_size, gfp_flags, &urb->transfer_dma); - if (mem == NULL) + if (mem == NULL) { + usb_free_urb(urb); return i; + } usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, ep_addr), mem, buf_size, complete_fn, context); diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 3f0871b..810eef4 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -407,18 +407,6 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, /* Decrease the module use count to match the first try_module_get. */ module_put(client->driver->driver.owner); - if (sd) { - /* We return errors from v4l2_subdev_call only if we have the - callback as the .s_config is not mandatory */ - int err = v4l2_subdev_call(sd, core, s_config, - info->irq, info->platform_data); - - if (err && err != -ENOIOCTLCMD) { - v4l2_device_unregister_subdev(sd); - sd = NULL; - } - } - error: /* If we have a client but no subdev, then something went wrong and we must unregister the client. */ @@ -428,9 +416,8 @@ error: } EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_board); -struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, +struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev, struct i2c_adapter *adapter, const char *client_type, - int irq, void *platform_data, u8 addr, const unsigned short *probe_addrs) { struct i2c_board_info info; @@ -440,12 +427,10 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, memset(&info, 0, sizeof(info)); strlcpy(info.type, client_type, sizeof(info.type)); info.addr = addr; - info.irq = irq; - info.platform_data = platform_data; return v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, probe_addrs); } -EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev_cfg); +EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev); /* Return i2c client address of v4l2_subdev. */ unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd) diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index 8f81efc..ef66d2a 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c @@ -569,7 +569,7 @@ static int user_to_new(struct v4l2_ext_control *c, int ret; u32 size; - ctrl->has_new = 1; + ctrl->is_new = 1; switch (ctrl->type) { case V4L2_CTRL_TYPE_INTEGER64: ctrl->val64 = c->value64; @@ -1280,8 +1280,12 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl) if (ctrl->done) continue; - for (i = 0; i < master->ncontrols; i++) - cur_to_new(master->cluster[i]); + for (i = 0; i < master->ncontrols; i++) { + if (master->cluster[i]) { + cur_to_new(master->cluster[i]); + master->cluster[i]->is_new = 1; + } + } /* Skip button controls and read-only controls. */ if (ctrl->type == V4L2_CTRL_TYPE_BUTTON || @@ -1340,12 +1344,15 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc) ctrl = ref->ctrl; memset(qc, 0, sizeof(*qc)); - qc->id = ctrl->id; + if (id >= V4L2_CID_PRIVATE_BASE) + qc->id = id; + else + qc->id = ctrl->id; strlcpy(qc->name, ctrl->name, sizeof(qc->name)); 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; @@ -1645,7 +1652,7 @@ static int try_or_set_control_cluster(struct v4l2_ctrl *master, bool set) if (ctrl == NULL) continue; - if (ctrl->has_new) { + if (ctrl->is_new) { /* Double check this: it may have changed since the last check in try_or_set_ext_ctrls(). */ if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) @@ -1719,13 +1726,13 @@ static int try_or_set_ext_ctrls(struct v4l2_ctrl_handler *hdl, v4l2_ctrl_lock(ctrl); - /* Reset the 'has_new' flags of the cluster */ + /* Reset the 'is_new' flags of the cluster */ for (j = 0; j < master->ncontrols; j++) if (master->cluster[j]) - master->cluster[j]->has_new = 0; + master->cluster[j]->is_new = 0; /* Copy the new caller-supplied control values. - user_to_new() sets 'has_new' to 1. */ + user_to_new() sets 'is_new' to 1. */ ret = cluster_walk(i, cs, helpers, user_to_new); if (!ret) @@ -1820,15 +1827,18 @@ static int set_ctrl(struct v4l2_ctrl *ctrl, s32 *val) int ret; int i; + if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) + return -EACCES; + v4l2_ctrl_lock(ctrl); - /* Reset the 'has_new' flags of the cluster */ + /* Reset the 'is_new' flags of the cluster */ for (i = 0; i < master->ncontrols; i++) if (master->cluster[i]) - master->cluster[i]->has_new = 0; + master->cluster[i]->is_new = 0; ctrl->val = *val; - ctrl->has_new = 1; + ctrl->is_new = 1; ret = try_or_set_control_cluster(master, false); if (!ret) ret = try_or_set_control_cluster(master, true); diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 359e232..341764a 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) diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 7fe6f92..ce64fe1 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 } @@ -126,11 +128,19 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, WARN_ON(sd->v4l2_dev != NULL); if (!try_module_get(sd->owner)) return -ENODEV; + sd->v4l2_dev = v4l2_dev; + if (sd->internal_ops && sd->internal_ops->registered) { + err = sd->internal_ops->registered(sd); + if (err) + return err; + } /* This just returns 0 if either of the two args is NULL */ err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler); - if (err) + if (err) { + if (sd->internal_ops && sd->internal_ops->unregistered) + sd->internal_ops->unregistered(sd); return err; - sd->v4l2_dev = v4l2_dev; + } spin_lock(&v4l2_dev->lock); list_add_tail(&sd->list, &v4l2_dev->subdevs); spin_unlock(&v4l2_dev->lock); @@ -146,6 +156,8 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) spin_lock(&sd->v4l2_dev->lock); list_del(&sd->list); spin_unlock(&sd->v4l2_dev->lock); + if (sd->internal_ops && sd->internal_ops->unregistered) + sd->internal_ops->unregistered(sd); sd->v4l2_dev = NULL; module_put(sd->owner); } diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 7e47f15..f51327e 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -1659,20 +1659,24 @@ static long __video_do_ioctl(struct file *file, { struct v4l2_dbg_register *p = arg; - if (!capable(CAP_SYS_ADMIN)) - ret = -EPERM; - else if (ops->vidioc_g_register) - ret = ops->vidioc_g_register(file, fh, p); + if (ops->vidioc_g_register) { + if (!capable(CAP_SYS_ADMIN)) + ret = -EPERM; + else + ret = ops->vidioc_g_register(file, fh, p); + } break; } case VIDIOC_DBG_S_REGISTER: { struct v4l2_dbg_register *p = arg; - if (!capable(CAP_SYS_ADMIN)) - ret = -EPERM; - else if (ops->vidioc_s_register) - ret = ops->vidioc_s_register(file, fh, p); + if (ops->vidioc_s_register) { + if (!capable(CAP_SYS_ADMIN)) + ret = -EPERM; + else + ret = ops->vidioc_s_register(file, fh, p); + } break; } #endif diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 019ee20..fa35639 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)); } diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 9cdc3bb..9f2bac5 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 diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 16fe4f9..0382332 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2864,7 +2864,7 @@ config MLX4_CORE default n config MLX4_DEBUG - bool "Verbose debugging output" if (MLX4_CORE && EMBEDDED) + bool "Verbose debugging output" if (MLX4_CORE && EXPERT) depends on MLX4_CORE default y ---help--- diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c index 62d6f88..aa07657 100644 --- a/drivers/net/arm/ks8695net.c +++ b/drivers/net/arm/ks8695net.c @@ -1644,7 +1644,7 @@ ks8695_cleanup(void) module_init(ks8695_init); module_exit(ks8695_cleanup); -MODULE_AUTHOR("Simtec Electronics") +MODULE_AUTHOR("Simtec Electronics"); MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" MODULENAME); diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 171782e..1024ae1 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -2470,6 +2470,10 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac if (!(dev->flags & IFF_MASTER)) goto out; + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + goto out; + if (!pskb_may_pull(skb, sizeof(struct lacpdu))) goto out; diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index f4e638c..5c6fba8 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -326,6 +326,10 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct goto out; } + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + goto out; + if (!pskb_may_pull(skb, arp_hdr_len(bond_dev))) goto out; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b1025b8..163e0b0 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2733,6 +2733,10 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack if (!slave || !slave_do_arp_validate(bond, slave)) goto out_unlock; + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + goto out_unlock; + if (!pskb_may_pull(skb, arp_hdr_len(dev))) goto out_unlock; diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index d5a9db6..986195e 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -117,6 +117,8 @@ source "drivers/net/can/sja1000/Kconfig" source "drivers/net/can/usb/Kconfig" +source "drivers/net/can/softing/Kconfig" + config CAN_DEBUG_DEVICES bool "CAN devices debugging messages" depends on CAN diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 07ca159..53c82a7 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_CAN_DEV) += can-dev.o can-dev-y := dev.o obj-y += usb/ +obj-y += softing/ obj-$(CONFIG_CAN_SJA1000) += sja1000/ obj-$(CONFIG_CAN_MSCAN) += mscan/ diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig new file mode 100644 index 0000000..92bd6bd --- /dev/null +++ b/drivers/net/can/softing/Kconfig @@ -0,0 +1,30 @@ +config CAN_SOFTING + tristate "Softing Gmbh CAN generic support" + depends on CAN_DEV + ---help--- + Support for CAN cards from Softing Gmbh & some cards + from Vector Gmbh. + Softing Gmbh CAN cards come with 1 or 2 physical busses. + Those cards typically use Dual Port RAM to communicate + with the host CPU. The interface is then identical for PCI + and PCMCIA cards. This driver operates on a platform device, + which has been created by softing_cs or softing_pci driver. + Warning: + The API of the card does not allow fine control per bus, but + controls the 2 busses on the card together. + As such, some actions (start/stop/busoff recovery) on 1 bus + must bring down the other bus too temporarily. + +config CAN_SOFTING_CS + tristate "Softing Gmbh CAN pcmcia cards" + depends on PCMCIA + select CAN_SOFTING + ---help--- + Support for PCMCIA cards from Softing Gmbh & some cards + from Vector Gmbh. + You need firmware for these, which you can get at + http://developer.berlios.de/projects/socketcan/ + This version of the driver is written against + firmware version 4.6 (softing-fw-4.6-binaries.tar.gz) + In order to use the card as CAN device, you need the Softing generic + support too. diff --git a/drivers/net/can/softing/Makefile b/drivers/net/can/softing/Makefile new file mode 100644 index 0000000..c5e5016 --- /dev/null +++ b/drivers/net/can/softing/Makefile @@ -0,0 +1,6 @@ + +softing-y := softing_main.o softing_fw.o +obj-$(CONFIG_CAN_SOFTING) += softing.o +obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o + +ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h new file mode 100644 index 0000000..7ec9f4d --- /dev/null +++ b/drivers/net/can/softing/softing.h @@ -0,0 +1,167 @@ +/* + * softing common interfaces + * + * by Kurt Van Dijck, 2008-2010 + */ + +#include <linux/atomic.h> +#include <linux/netdevice.h> +#include <linux/ktime.h> +#include <linux/mutex.h> +#include <linux/spinlock.h> +#include <linux/can.h> +#include <linux/can/dev.h> + +#include "softing_platform.h" + +struct softing; + +struct softing_priv { + struct can_priv can; /* must be the first member! */ + struct net_device *netdev; + struct softing *card; + struct { + int pending; + /* variables wich hold the circular buffer */ + int echo_put; + int echo_get; + } tx; + struct can_bittiming_const btr_const; + int index; + uint8_t output; + uint16_t chip; +}; +#define netdev2softing(netdev) ((struct softing_priv *)netdev_priv(netdev)) + +struct softing { + const struct softing_platform_data *pdat; + struct platform_device *pdev; + struct net_device *net[2]; + spinlock_t spin; /* protect this structure & DPRAM access */ + ktime_t ts_ref; + ktime_t ts_overflow; /* timestamp overflow value, in ktime */ + + struct { + /* indication of firmware status */ + int up; + /* protection of the 'up' variable */ + struct mutex lock; + } fw; + struct { + int nr; + int requested; + int svc_count; + unsigned int dpram_position; + } irq; + struct { + int pending; + int last_bus; + /* + * keep the bus that last tx'd a message, + * in order to let every netdev queue resume + */ + } tx; + __iomem uint8_t *dpram; + unsigned long dpram_phys; + unsigned long dpram_size; + struct { + uint16_t fw_version, hw_version, license, serial; + uint16_t chip[2]; + unsigned int freq; /* remote cpu's operating frequency */ + } id; +}; + +extern int softing_default_output(struct net_device *netdev); + +extern ktime_t softing_raw2ktime(struct softing *card, u32 raw); + +extern int softing_chip_poweron(struct softing *card); + +extern int softing_bootloader_command(struct softing *card, int16_t cmd, + const char *msg); + +/* Load firmware after reset */ +extern int softing_load_fw(const char *file, struct softing *card, + __iomem uint8_t *virt, unsigned int size, int offset); + +/* Load final application firmware after bootloader */ +extern int softing_load_app_fw(const char *file, struct softing *card); + +/* + * enable or disable irq + * only called with fw.lock locked + */ +extern int softing_enable_irq(struct softing *card, int enable); + +/* start/stop 1 bus on card */ +extern int softing_startstop(struct net_device *netdev, int up); + +/* netif_rx() */ +extern int softing_netdev_rx(struct net_device *netdev, + const struct can_frame *msg, ktime_t ktime); + +/* SOFTING DPRAM mappings */ +#define DPRAM_RX 0x0000 + #define DPRAM_RX_SIZE 32 + #define DPRAM_RX_CNT 16 +#define DPRAM_RX_RD 0x0201 /* uint8_t */ +#define DPRAM_RX_WR 0x0205 /* uint8_t */ +#define DPRAM_RX_LOST 0x0207 /* uint8_t */ + +#define DPRAM_FCT_PARAM 0x0300 /* int16_t [20] */ +#define DPRAM_FCT_RESULT 0x0328 /* int16_t */ +#define DPRAM_FCT_HOST 0x032b /* uint16_t */ + +#define DPRAM_INFO_BUSSTATE 0x0331 /* uint16_t */ +#define DPRAM_INFO_BUSSTATE2 0x0335 /* uint16_t */ +#define DPRAM_INFO_ERRSTATE 0x0339 /* uint16_t */ +#define DPRAM_INFO_ERRSTATE2 0x033d /* uint16_t */ +#define DPRAM_RESET 0x0341 /* uint16_t */ +#define DPRAM_CLR_RECV_FIFO 0x0345 /* uint16_t */ +#define DPRAM_RESET_TIME 0x034d /* uint16_t */ +#define DPRAM_TIME 0x0350 /* uint64_t */ +#define DPRAM_WR_START 0x0358 /* uint8_t */ +#define DPRAM_WR_END 0x0359 /* uint8_t */ +#define DPRAM_RESET_RX_FIFO 0x0361 /* uint16_t */ +#define DPRAM_RESET_TX_FIFO 0x0364 /* uint8_t */ +#define DPRAM_READ_FIFO_LEVEL 0x0365 /* uint8_t */ +#define DPRAM_RX_FIFO_LEVEL 0x0366 /* uint16_t */ +#define DPRAM_TX_FIFO_LEVEL 0x0366 /* uint16_t */ + +#define DPRAM_TX 0x0400 /* uint16_t */ + #define DPRAM_TX_SIZE 16 + #define DPRAM_TX_CNT 32 +#define DPRAM_TX_RD 0x0601 /* uint8_t */ +#define DPRAM_TX_WR 0x0605 /* uint8_t */ + +#define DPRAM_COMMAND 0x07e0 /* uint16_t */ +#define DPRAM_RECEIPT 0x07f0 /* uint16_t */ +#define DPRAM_IRQ_TOHOST 0x07fe /* uint8_t */ +#define DPRAM_IRQ_TOCARD 0x07ff /* uint8_t */ + +#define DPRAM_V2_RESET 0x0e00 /* uint8_t */ +#define DPRAM_V2_IRQ_TOHOST 0x0e02 /* uint8_t */ + +#define TXMAX (DPRAM_TX_CNT - 1) + +/* DPRAM return codes */ +#define RES_NONE 0 +#define RES_OK 1 +#define RES_NOK 2 +#define RES_UNKNOWN 3 +/* DPRAM flags */ +#define CMD_TX 0x01 +#define CMD_ACK 0x02 +#define CMD_XTD 0x04 +#define CMD_RTR 0x08 +#define CMD_ERR 0x10 +#define CMD_BUS2 0x80 + +/* returned fifo entry bus state masks */ +#define SF_MASK_BUSOFF 0x80 +#define SF_MASK_EPASSIVE 0x60 + +/* bus states */ +#define STATE_BUSOFF 2 +#define STATE_EPASSIVE 1 +#define STATE_EACTIVE 0 diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c new file mode 100644 index 0000000..300fe75 --- /dev/null +++ b/drivers/net/can/softing/softing_cs.c @@ -0,0 +1,359 @@ +/* + * Copyright (C) 2008-2010 + * + * - Kurt Van Dijck, EIA Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/kernel.h> + +#include <pcmcia/cistpl.h> +#include <pcmcia/ds.h> + +#include "softing_platform.h" + +static int softingcs_index; +static spinlock_t softingcs_index_lock; + +static int softingcs_reset(struct platform_device *pdev, int v); +static int softingcs_enable_irq(struct platform_device *pdev, int v); + +/* + * platform_data descriptions + */ +#define MHZ (1000*1000) +static const struct softing_platform_data softingcs_platform_data[] = { +{ + .name = "CANcard", + .manf = 0x0168, .prod = 0x001, + .generation = 1, + .nbus = 2, + .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, + .dpram_size = 0x0800, + .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, + .reset = softingcs_reset, + .enable_irq = softingcs_enable_irq, +}, { + .name = "CANcard-NEC", + .manf = 0x0168, .prod = 0x002, + .generation = 1, + .nbus = 2, + .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4, + .dpram_size = 0x0800, + .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, + .reset = softingcs_reset, + .enable_irq = softingcs_enable_irq, +}, { + .name = "CANcard-SJA", + .manf = 0x0168, .prod = 0x004, + .generation = 1, + .nbus = 2, + .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, + .dpram_size = 0x0800, + .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, + .reset = softingcs_reset, + .enable_irq = softingcs_enable_irq, +}, { + .name = "CANcard-2", + .manf = 0x0168, .prod = 0x005, + .generation = 2, + .nbus = 2, + .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, + .dpram_size = 0x1000, + .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, + .reset = softingcs_reset, + .enable_irq = NULL, +}, { + .name = "Vector-CANcard", + .manf = 0x0168, .prod = 0x081, + .generation = 1, + .nbus = 2, + .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, + .dpram_size = 0x0800, + .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, + .reset = softingcs_reset, + .enable_irq = softingcs_enable_irq, +}, { + .name = "Vector-CANcard-SJA", + .manf = 0x0168, .prod = 0x084, + .generation = 1, + .nbus = 2, + .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4, + .dpram_size = 0x0800, + .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",}, + .reset = softingcs_reset, + .enable_irq = softingcs_enable_irq, +}, { + .name = "Vector-CANcard-2", + .manf = 0x0168, .prod = 0x085, + .generation = 2, + .nbus = 2, + .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, + .dpram_size = 0x1000, + .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, + .reset = softingcs_reset, + .enable_irq = NULL, +}, { + .name = "EDICcard-NEC", + .manf = 0x0168, .prod = 0x102, + .generation = 1, + .nbus = 2, + .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4, + .dpram_size = 0x0800, + .boot = {0x0000, 0x000000, fw_dir "bcard.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",}, + .reset = softingcs_reset, + .enable_irq = softingcs_enable_irq, +}, { + .name = "EDICcard-2", + .manf = 0x0168, .prod = 0x105, + .generation = 2, + .nbus = 2, + .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4, + .dpram_size = 0x1000, + .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",}, + .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",}, + .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",}, + .reset = softingcs_reset, + .enable_irq = NULL, +}, { + 0, 0, +}, +}; + +MODULE_FIRMWARE(fw_dir "bcard.bin"); +MODULE_FIRMWARE(fw_dir "ldcard.bin"); +MODULE_FIRMWARE(fw_dir "cancard.bin"); +MODULE_FIRMWARE(fw_dir "cansja.bin"); + +MODULE_FIRMWARE(fw_dir "bcard2.bin"); +MODULE_FIRMWARE(fw_dir "ldcard2.bin"); +MODULE_FIRMWARE(fw_dir "cancrd2.bin"); + +static __devinit const struct softing_platform_data +*softingcs_find_platform_data(unsigned int manf, unsigned int prod) +{ + const struct softing_platform_data *lp; + + for (lp = softingcs_platform_data; lp->manf; ++lp) { + if ((lp->manf == manf) && (lp->prod == prod)) + return lp; + } + return NULL; +} + +/* + * platformdata callbacks + */ +static int softingcs_reset(struct platform_device *pdev, int v) +{ + struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); + + dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20); + return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20); +} + +static int softingcs_enable_irq(struct platform_device *pdev, int v) +{ + struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent); + + dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0); + return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0); +} + +/* + * pcmcia check + */ +static __devinit int softingcs_probe_config(struct pcmcia_device *pcmcia, + void *priv_data) +{ + struct softing_platform_data *pdat = priv_data; + struct resource *pres; + int memspeed = 0; + + WARN_ON(!pdat); + pres = pcmcia->resource[PCMCIA_IOMEM_0]; + if (resource_size(pres) < 0x1000) + return -ERANGE; + + pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE; + if (pdat->generation < 2) { + pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8; + memspeed = 3; + } else { + pres->flags |= WIN_DATA_WIDTH_16; + } + return pcmcia_request_window(pcmcia, pres, memspeed); +} + +static __devexit void softingcs_remove(struct pcmcia_device *pcmcia) +{ + struct platform_device *pdev = pcmcia->priv; + + /* free bits */ + platform_device_unregister(pdev); + /* release pcmcia stuff */ + pcmcia_disable_device(pcmcia); +} + +/* + * platform_device wrapper + * pdev->resource has 2 entries: io & irq + */ +static void softingcs_pdev_release(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + kfree(pdev); +} + +static __devinit int softingcs_probe(struct pcmcia_device *pcmcia) +{ + int ret; + struct platform_device *pdev; + const struct softing_platform_data *pdat; + struct resource *pres; + struct dev { + struct platform_device pdev; + struct resource res[2]; + } *dev; + + /* find matching platform_data */ + pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id); + if (!pdat) + return -ENOTTY; + + /* setup pcmcia device */ + pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM | + CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC; + ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat); + if (ret) + goto pcmcia_failed; + + ret = pcmcia_enable_device(pcmcia); + if (ret < 0) + goto pcmcia_failed; + + pres = pcmcia->resource[PCMCIA_IOMEM_0]; + if (!pres) { + ret = -EBADF; + goto pcmcia_bad; + } + + /* create softing platform device */ + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + ret = -ENOMEM; + goto mem_failed; + } + dev->pdev.resource = dev->res; + dev->pdev.num_resources = ARRAY_SIZE(dev->res); + dev->pdev.dev.release = softingcs_pdev_release; + + pdev = &dev->pdev; + pdev->dev.platform_data = (void *)pdat; + pdev->dev.parent = &pcmcia->dev; + pcmcia->priv = pdev; + + /* platform device resources */ + pdev->resource[0].flags = IORESOURCE_MEM; + pdev->resource[0].start = pres->start; + pdev->resource[0].end = pres->end; + + pdev->resource[1].flags = IORESOURCE_IRQ; + pdev->resource[1].start = pcmcia->irq; + pdev->resource[1].end = pdev->resource[1].start; + + /* platform device setup */ + spin_lock(&softingcs_index_lock); + pdev->id = softingcs_index++; + spin_unlock(&softingcs_index_lock); + pdev->name = "softing"; + dev_set_name(&pdev->dev, "softingcs.%i", pdev->id); + ret = platform_device_register(pdev); + if (ret < 0) + goto platform_failed; + + dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev)); + return 0; + +platform_failed: + kfree(dev); +mem_failed: +pcmcia_bad: +pcmcia_failed: + pcmcia_disable_device(pcmcia); + pcmcia->priv = NULL; + return ret ?: -ENODEV; +} + +static /*const*/ struct pcmcia_device_id softingcs_ids[] = { + /* softing */ + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001), + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002), + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004), + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005), + /* vector, manufacturer? */ + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081), + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084), + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085), + /* EDIC */ + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102), + PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105), + PCMCIA_DEVICE_NULL, +}; + +MODULE_DEVICE_TABLE(pcmcia, softingcs_ids); + +static struct pcmcia_driver softingcs_driver = { + .owner = THIS_MODULE, + .name = "softingcs", + .id_table = softingcs_ids, + .probe = softingcs_probe, + .remove = __devexit_p(softingcs_remove), +}; + +static int __init softingcs_start(void) +{ + spin_lock_init(&softingcs_index_lock); + return pcmcia_register_driver(&softingcs_driver); +} + +static void __exit softingcs_stop(void) +{ + pcmcia_unregister_driver(&softingcs_driver); +} + +module_init(softingcs_start); +module_exit(softingcs_stop); + +MODULE_DESCRIPTION("softing CANcard driver" + ", links PCMCIA card to softing driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c new file mode 100644 index 0000000..b520784 --- /dev/null +++ b/drivers/net/can/softing/softing_fw.c @@ -0,0 +1,691 @@ +/* + * Copyright (C) 2008-2010 + * + * - Kurt Van Dijck, EIA Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/firmware.h> +#include <linux/sched.h> +#include <asm/div64.h> + +#include "softing.h" + +/* + * low level DPRAM command. + * Make sure that card->dpram[DPRAM_FCT_HOST] is preset + */ +static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector, + const char *msg) +{ + int ret; + unsigned long stamp; + + iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]); + iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]); + iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]); + /* be sure to flush this to the card */ + wmb(); + stamp = jiffies + 1 * HZ; + /* wait for card */ + do { + /* DPRAM_FCT_HOST is _not_ aligned */ + ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) + + (ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8); + /* don't have any cached variables */ + rmb(); + if (ret == RES_OK) + /* read return-value now */ + return ioread16(&card->dpram[DPRAM_FCT_RESULT]); + + if ((ret != vector) || time_after(jiffies, stamp)) + break; + /* process context => relax */ + usleep_range(500, 10000); + } while (1); + + ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; + dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n", msg, ret); + return ret; +} + +static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg) +{ + int ret; + + ret = _softing_fct_cmd(card, cmd, 0, msg); + if (ret > 0) { + dev_alert(&card->pdev->dev, "%s returned %u\n", msg, ret); + ret = -EIO; + } + return ret; +} + +int softing_bootloader_command(struct softing *card, int16_t cmd, + const char *msg) +{ + int ret; + unsigned long stamp; + + iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]); + iowrite16(cmd, &card->dpram[DPRAM_COMMAND]); + /* be sure to flush this to the card */ + wmb(); + stamp = jiffies + 3 * HZ; + /* wait for card */ + do { + ret = ioread16(&card->dpram[DPRAM_RECEIPT]); + /* don't have any cached variables */ + rmb(); + if (ret == RES_OK) + return 0; + if (time_after(jiffies, stamp)) + break; + /* process context => relax */ + usleep_range(500, 10000); + } while (!signal_pending(current)); + + ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED; + dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n", msg, ret); + return ret; +} + +static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr, + uint16_t *plen, const uint8_t **pdat) +{ + uint16_t checksum[2]; + const uint8_t *mem; + const uint8_t *end; + + /* + * firmware records are a binary, unaligned stream composed of: + * uint16_t type; + * uint32_t addr; + * uint16_t len; + * uint8_t dat[len]; + * uint16_t checksum; + * all values in little endian. + * We could define a struct for this, with __attribute__((packed)), + * but would that solve the alignment in _all_ cases (cfr. the + * struct itself may be an odd address)? + * + * I chose to use leXX_to_cpup() since this solves both + * endianness & alignment. + */ + mem = *pmem; + *ptype = le16_to_cpup((void *)&mem[0]); + *paddr = le32_to_cpup((void *)&mem[2]); + *plen = le16_to_cpup((void *)&mem[6]); + *pdat = &mem[8]; + /* verify checksum */ + end = &mem[8 + *plen]; + checksum[0] = le16_to_cpup((void *)end); + for (checksum[1] = 0; mem < end; ++mem) + checksum[1] += *mem; + if (checksum[0] != checksum[1]) + return -EINVAL; + /* increment */ + *pmem += 10 + *plen; + return 0; +} + +int softing_load_fw(const char *file, struct softing *card, + __iomem uint8_t *dpram, unsigned int size, int offset) +{ + const struct firmware *fw; + int ret; + const uint8_t *mem, *end, *dat; + uint16_t type, len; + uint32_t addr; + uint8_t *buf = NULL; + int buflen = 0; + int8_t type_end = 0; + + ret = request_firmware(&fw, file, &card->pdev->dev); + if (ret < 0) + return ret; + dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes" + ", offset %c0x%04x\n", + card->pdat->name, file, (unsigned int)fw->size, + (offset >= 0) ? '+' : '-', (unsigned int)abs(offset)); + /* parse the firmware */ + mem = fw->data; + end = &mem[fw->size]; + /* look for header record */ + ret = fw_parse(&mem, &type, &addr, &len, &dat); + if (ret < 0) + goto failed; + if (type != 0xffff) + goto failed; + if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) { + ret = -EINVAL; + goto failed; + } + /* ok, we had a header */ + while (mem < end) { + ret = fw_parse(&mem, &type, &addr, &len, &dat); + if (ret < 0) + goto failed; + if (type == 3) { + /* start address, not used here */ + continue; + } else if (type == 1) { + /* eof */ + type_end = 1; + break; + } else if (type != 0) { + ret = -EINVAL; + goto failed; + } + + if ((addr + len + offset) > size) + goto failed; + memcpy_toio(&dpram[addr + offset], dat, len); + /* be sure to flush caches from IO space */ + mb(); + if (len > buflen) { + /* align buflen */ + buflen = (len + (1024-1)) & ~(1024-1); + buf = krealloc(buf, buflen, GFP_KERNEL); + if (!buf) { + ret = -ENOMEM; + goto failed; + } + } + /* verify record data */ + memcpy_fromio(buf, &dpram[addr + offset], len); + if (memcmp(buf, dat, len)) { + /* is not ok */ + dev_alert(&card->pdev->dev, "DPRAM readback failed\n"); + ret = -EIO; + goto failed; + } + } + if (!type_end) + /* no end record seen */ + goto failed; + ret = 0; +failed: + kfree(buf); + release_firmware(fw); + if (ret < 0) + dev_info(&card->pdev->dev, "firmware %s failed\n", file); + return ret; +} + +int softing_load_app_fw(const char *file, struct softing *card) +{ + const struct firmware *fw; + const uint8_t *mem, *end, *dat; + int ret, j; + uint16_t type, len; + uint32_t addr, start_addr = 0; + unsigned int sum, rx_sum; + int8_t type_end = 0, type_entrypoint = 0; + + ret = request_firmware(&fw, file, &card->pdev->dev); + if (ret) { + dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n", + file, ret); + return ret; + } + dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n", + file, (unsigned long)fw->size); + /* parse the firmware */ + mem = fw->data; + end = &mem[fw->size]; + /* look for header record */ + ret = fw_parse(&mem, &type, &addr, &len, &dat); + if (ret) + goto failed; + ret = -EINVAL; + if (type != 0xffff) { + dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n", + type); + goto failed; + } + if (strncmp("Structured Binary Format, Softing GmbH", dat, len)) { + dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n", + len, dat); + goto failed; + } + /* ok, we had a header */ + while (mem < end) { + ret = fw_parse(&mem, &type, &addr, &len, &dat); + if (ret) + goto failed; + + if (type == 3) { + /* start address */ + start_addr = addr; + type_entrypoint = 1; + continue; + } else if (type == 1) { + /* eof */ + type_end = 1; + break; + } else if (type != 0) { + dev_alert(&card->pdev->dev, + "unknown record type 0x%04x\n", type); + ret = -EINVAL; + goto failed; + } + + /* regualar data */ + for (sum = 0, j = 0; j < len; ++j) + sum += dat[j]; + /* work in 16bit (target) */ + sum &= 0xffff; + + memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len); + iowrite32(card->pdat->app.offs + card->pdat->app.addr, + &card->dpram[DPRAM_COMMAND + 2]); + iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]); + iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]); + iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]); + ret = softing_bootloader_command(card, 1, "loading app."); + if (ret < 0) + goto failed; + /* verify checksum */ + rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]); + if (rx_sum != sum) { + dev_alert(&card->pdev->dev, "SRAM seems to be damaged" + ", wanted 0x%04x, got 0x%04x\n", sum, rx_sum); + ret = -EIO; + goto failed; + } + } + if (!type_end || !type_entrypoint) + goto failed; + /* start application in card */ + iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]); + iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]); + ret = softing_bootloader_command(card, 3, "start app."); + if (ret < 0) + goto failed; + ret = 0; +failed: + release_firmware(fw); + if (ret < 0) + dev_info(&card->pdev->dev, "firmware %s failed\n", file); + return ret; +} + +static int softing_reset_chip(struct softing *card) +{ + int ret; + + do { + /* reset chip */ + iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]); + iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]); + iowrite8(1, &card->dpram[DPRAM_RESET]); + iowrite8(0, &card->dpram[DPRAM_RESET+1]); + + ret = softing_fct_cmd(card, 0, "reset_can"); + if (!ret) + break; + if (signal_pending(current)) + /* don't wait any longer */ + break; + } while (1); + card->tx.pending = 0; + return ret; +} + +int softing_chip_poweron(struct softing *card) +{ + int ret; + /* sync */ + ret = _softing_fct_cmd(card, 99, 0x55, "sync-a"); + if (ret < 0) + goto failed; + + ret = _softing_fct_cmd(card, 99, 0xaa, "sync-b"); + if (ret < 0) + goto failed; + + ret = softing_reset_chip(card); + if (ret < 0) + goto failed; + /* get_serial */ + ret = softing_fct_cmd(card, 43, "get_serial_number"); + if (ret < 0) + goto failed; + card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]); + /* get_version */ + ret = softing_fct_cmd(card, 12, "get_version"); + if (ret < 0) + goto failed; + card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]); + card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]); + card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]); + card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]); + card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]); + return 0; +failed: + return ret; +} + +static void softing_initialize_timestamp(struct softing *card) +{ + uint64_t ovf; + + card->ts_ref = ktime_get(); + + /* 16MHz is the reference */ + ovf = 0x100000000ULL * 16; + do_div(ovf, card->pdat->freq ?: 16); + + card->ts_overflow = ktime_add_us(ktime_set(0, 0), ovf); +} + +ktime_t softing_raw2ktime(struct softing *card, u32 raw) +{ + uint64_t rawl; + ktime_t now, real_offset; + ktime_t target; + ktime_t tmp; + + now = ktime_get(); + real_offset = ktime_sub(ktime_get_real(), now); + + /* find nsec from card */ + rawl = raw * 16; + do_div(rawl, card->pdat->freq ?: 16); + target = ktime_add_us(card->ts_ref, rawl); + /* test for overflows */ + tmp = ktime_add(target, card->ts_overflow); + while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) { + card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow); + target = tmp; + tmp = ktime_add(target, card->ts_overflow); + } + return ktime_add(target, real_offset); +} + +static inline int softing_error_reporting(struct net_device *netdev) +{ + struct softing_priv *priv = netdev_priv(netdev); + + return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) + ? 1 : 0; +} + +int softing_startstop(struct net_device *dev, int up) +{ + int ret; + struct softing *card; + struct softing_priv *priv; + struct net_device *netdev; + int bus_bitmask_start; + int j, error_reporting; + struct can_frame msg; + const struct can_bittiming *bt; + + priv = netdev_priv(dev); + card = priv->card; + + if (!card->fw.up) + return -EIO; + + ret = mutex_lock_interruptible(&card->fw.lock); + if (ret) + return ret; + + bus_bitmask_start = 0; + if (dev && up) + /* prepare to start this bus as well */ + bus_bitmask_start |= (1 << priv->index); + /* bring netdevs down */ + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + netdev = card->net[j]; + if (!netdev) + continue; + priv = netdev_priv(netdev); + + if (dev != netdev) + netif_stop_queue(netdev); + + if (netif_running(netdev)) { + if (dev != netdev) + bus_bitmask_start |= (1 << j); + priv->tx.pending = 0; + priv->tx.echo_put = 0; + priv->tx.echo_get = 0; + /* + * this bus' may just have called open_candev() + * which is rather stupid to call close_candev() + * already + * but we may come here from busoff recovery too + * in which case the echo_skb _needs_ flushing too. + * just be sure to call open_candev() again + */ + close_candev(netdev); + } + priv->can.state = CAN_STATE_STOPPED; + } + card->tx.pending = 0; + + softing_enable_irq(card, 0); + ret = softing_reset_chip(card); + if (ret) + goto failed; + if (!bus_bitmask_start) + /* no busses to be brought up */ + goto card_done; + + if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2) + && (softing_error_reporting(card->net[0]) + != softing_error_reporting(card->net[1]))) { + dev_alert(&card->pdev->dev, + "err_reporting flag differs for busses\n"); + goto invalid; + } + error_reporting = 0; + if (bus_bitmask_start & 1) { + netdev = card->net[0]; + priv = netdev_priv(netdev); + error_reporting += softing_error_reporting(netdev); + /* init chip 1 */ + bt = &priv->can.bittiming; + iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); + iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); + iowrite16(bt->phase_seg1 + bt->prop_seg, + &card->dpram[DPRAM_FCT_PARAM + 6]); + iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); + iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, + &card->dpram[DPRAM_FCT_PARAM + 10]); + ret = softing_fct_cmd(card, 1, "initialize_chip[0]"); + if (ret < 0) + goto failed; + /* set mode */ + iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); + iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); + ret = softing_fct_cmd(card, 3, "set_mode[0]"); + if (ret < 0) + goto failed; + /* set filter */ + /* 11bit id & mask */ + iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); + iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); + /* 29bit id.lo & mask.lo & id.hi & mask.hi */ + iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); + iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); + iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); + iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); + ret = softing_fct_cmd(card, 7, "set_filter[0]"); + if (ret < 0) + goto failed; + /* set output control */ + iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); + ret = softing_fct_cmd(card, 5, "set_output[0]"); + if (ret < 0) + goto failed; + } + if (bus_bitmask_start & 2) { + netdev = card->net[1]; + priv = netdev_priv(netdev); + error_reporting += softing_error_reporting(netdev); + /* init chip2 */ + bt = &priv->can.bittiming; + iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]); + iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]); + iowrite16(bt->phase_seg1 + bt->prop_seg, + &card->dpram[DPRAM_FCT_PARAM + 6]); + iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]); + iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0, + &card->dpram[DPRAM_FCT_PARAM + 10]); + ret = softing_fct_cmd(card, 2, "initialize_chip[1]"); + if (ret < 0) + goto failed; + /* set mode2 */ + iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]); + iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]); + ret = softing_fct_cmd(card, 4, "set_mode[1]"); + if (ret < 0) + goto failed; + /* set filter2 */ + /* 11bit id & mask */ + iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]); + iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]); + /* 29bit id.lo & mask.lo & id.hi & mask.hi */ + iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]); + iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]); + iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]); + iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]); + ret = softing_fct_cmd(card, 8, "set_filter[1]"); + if (ret < 0) + goto failed; + /* set output control2 */ + iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]); + ret = softing_fct_cmd(card, 6, "set_output[1]"); + if (ret < 0) + goto failed; + } + /* enable_error_frame */ + /* + * Error reporting is switched off at the moment since + * the receiving of them is not yet 100% verified + * This should be enabled sooner or later + * + if (error_reporting) { + ret = softing_fct_cmd(card, 51, "enable_error_frame"); + if (ret < 0) + goto failed; + } + */ + /* initialize interface */ + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]); + iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]); + ret = softing_fct_cmd(card, 17, "initialize_interface"); + if (ret < 0) + goto failed; + /* enable_fifo */ + ret = softing_fct_cmd(card, 36, "enable_fifo"); + if (ret < 0) + goto failed; + /* enable fifo tx ack */ + ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]"); + if (ret < 0) + goto failed; + /* enable fifo tx ack2 */ + ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]"); + if (ret < 0) + goto failed; + /* start_chip */ + ret = softing_fct_cmd(card, 11, "start_chip"); + if (ret < 0) + goto failed; + iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]); + iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]); + if (card->pdat->generation < 2) { + iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); + /* flush the DPRAM caches */ + wmb(); + } + + softing_initialize_timestamp(card); + + /* + * do socketcan notifications/status changes + * from here, no errors should occur, or the failed: part + * must be reviewed + */ + memset(&msg, 0, sizeof(msg)); + msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED; + msg.can_dlc = CAN_ERR_DLC; + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + if (!(bus_bitmask_start & (1 << j))) + continue; + netdev = card->net[j]; + if (!netdev) + continue; + priv = netdev_priv(netdev); + priv->can.state = CAN_STATE_ERROR_ACTIVE; + open_candev(netdev); + if (dev != netdev) { + /* notify other busses on the restart */ + softing_netdev_rx(netdev, &msg, ktime_set(0, 0)); + ++priv->can.can_stats.restarts; + } + netif_wake_queue(netdev); + } + + /* enable interrupts */ + ret = softing_enable_irq(card, 1); + if (ret) + goto failed; +card_done: + mutex_unlock(&card->fw.lock); + return 0; +invalid: + ret = -EINVAL; +failed: + softing_enable_irq(card, 0); + softing_reset_chip(card); + mutex_unlock(&card->fw.lock); + /* bring all other interfaces down */ + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + netdev = card->net[j]; + if (!netdev) + continue; + dev_close(netdev); + } + return ret; +} + +int softing_default_output(struct net_device *netdev) +{ + struct softing_priv *priv = netdev_priv(netdev); + struct softing *card = priv->card; + + switch (priv->chip) { + case 1000: + return (card->pdat->generation < 2) ? 0xfb : 0xfa; + case 5: + return 0x60; + default: + return 0x40; + } +} diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c new file mode 100644 index 0000000..5157e15 --- /dev/null +++ b/drivers/net/can/softing/softing_main.c @@ -0,0 +1,893 @@ +/* + * Copyright (C) 2008-2010 + * + * - Kurt Van Dijck, EIA Electronics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/version.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/interrupt.h> + +#include "softing.h" + +#define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1) + +/* + * test is a specific CAN netdev + * is online (ie. up 'n running, not sleeping, not busoff + */ +static inline int canif_is_active(struct net_device *netdev) +{ + struct can_priv *can = netdev_priv(netdev); + + if (!netif_running(netdev)) + return 0; + return (can->state <= CAN_STATE_ERROR_PASSIVE); +} + +/* reset DPRAM */ +static inline void softing_set_reset_dpram(struct softing *card) +{ + if (card->pdat->generation >= 2) { + spin_lock_bh(&card->spin); + iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1, + &card->dpram[DPRAM_V2_RESET]); + spin_unlock_bh(&card->spin); + } +} + +static inline void softing_clr_reset_dpram(struct softing *card) +{ + if (card->pdat->generation >= 2) { + spin_lock_bh(&card->spin); + iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1, + &card->dpram[DPRAM_V2_RESET]); + spin_unlock_bh(&card->spin); + } +} + +/* trigger the tx queue-ing */ +static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct softing_priv *priv = netdev_priv(dev); + struct softing *card = priv->card; + int ret; + uint8_t *ptr; + uint8_t fifo_wr, fifo_rd; + struct can_frame *cf = (struct can_frame *)skb->data; + uint8_t buf[DPRAM_TX_SIZE]; + + if (can_dropped_invalid_skb(dev, skb)) + return NETDEV_TX_OK; + + spin_lock(&card->spin); + + ret = NETDEV_TX_BUSY; + if (!card->fw.up || + (card->tx.pending >= TXMAX) || + (priv->tx.pending >= TX_ECHO_SKB_MAX)) + goto xmit_done; + fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]); + fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]); + if (fifo_wr == fifo_rd) + /* fifo full */ + goto xmit_done; + memset(buf, 0, sizeof(buf)); + ptr = buf; + *ptr = CMD_TX; + if (cf->can_id & CAN_RTR_FLAG) + *ptr |= CMD_RTR; + if (cf->can_id & CAN_EFF_FLAG) + *ptr |= CMD_XTD; + if (priv->index) + *ptr |= CMD_BUS2; + ++ptr; + *ptr++ = cf->can_dlc; + *ptr++ = (cf->can_id >> 0); + *ptr++ = (cf->can_id >> 8); + if (cf->can_id & CAN_EFF_FLAG) { + *ptr++ = (cf->can_id >> 16); + *ptr++ = (cf->can_id >> 24); + } else { + /* increment 1, not 2 as you might think */ + ptr += 1; + } + if (!(cf->can_id & CAN_RTR_FLAG)) + memcpy(ptr, &cf->data[0], cf->can_dlc); + memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr], + buf, DPRAM_TX_SIZE); + if (++fifo_wr >= DPRAM_TX_CNT) + fifo_wr = 0; + iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]); + card->tx.last_bus = priv->index; + ++card->tx.pending; + ++priv->tx.pending; + can_put_echo_skb(skb, dev, priv->tx.echo_put); + ++priv->tx.echo_put; + if (priv->tx.echo_put >= TX_ECHO_SKB_MAX) + priv->tx.echo_put = 0; + /* can_put_echo_skb() saves the skb, safe to return TX_OK */ + ret = NETDEV_TX_OK; +xmit_done: + spin_unlock(&card->spin); + if (card->tx.pending >= TXMAX) { + int j; + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + if (card->net[j]) + netif_stop_queue(card->net[j]); + } + } + if (ret != NETDEV_TX_OK) + netif_stop_queue(dev); + + return ret; +} + +/* + * shortcut for skb delivery + */ +int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg, + ktime_t ktime) +{ + struct sk_buff *skb; + struct can_frame *cf; + + skb = alloc_can_skb(netdev, &cf); + if (!skb) + return -ENOMEM; + memcpy(cf, msg, sizeof(*msg)); + skb->tstamp = ktime; + return netif_rx(skb); +} + +/* + * softing_handle_1 + * pop 1 entry from the DPRAM queue, and process + */ +static int softing_handle_1(struct softing *card) +{ + struct net_device *netdev; + struct softing_priv *priv; + ktime_t ktime; + struct can_frame msg; + int cnt = 0, lost_msg; + uint8_t fifo_rd, fifo_wr, cmd; + uint8_t *ptr; + uint32_t tmp_u32; + uint8_t buf[DPRAM_RX_SIZE]; + + memset(&msg, 0, sizeof(msg)); + /* test for lost msgs */ + lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]); + if (lost_msg) { + int j; + /* reset condition */ + iowrite8(0, &card->dpram[DPRAM_RX_LOST]); + /* prepare msg */ + msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL; + msg.can_dlc = CAN_ERR_DLC; + msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + /* + * service to all busses, we don't know which it was applicable + * but only service busses that are online + */ + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + netdev = card->net[j]; + if (!netdev) + continue; + if (!canif_is_active(netdev)) + /* a dead bus has no overflows */ + continue; + ++netdev->stats.rx_over_errors; + softing_netdev_rx(netdev, &msg, ktime_set(0, 0)); + } + /* prepare for other use */ + memset(&msg, 0, sizeof(msg)); + ++cnt; + } + + fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]); + fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]); + + if (++fifo_rd >= DPRAM_RX_CNT) + fifo_rd = 0; + if (fifo_wr == fifo_rd) + return cnt; + + memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd], + DPRAM_RX_SIZE); + mb(); + /* trigger dual port RAM */ + iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]); + + ptr = buf; + cmd = *ptr++; + if (cmd == 0xff) + /* not quite usefull, probably the card has got out */ + return 0; + netdev = card->net[0]; + if (cmd & CMD_BUS2) + netdev = card->net[1]; + priv = netdev_priv(netdev); + + if (cmd & CMD_ERR) { + uint8_t can_state, state; + + state = *ptr++; + + msg.can_id = CAN_ERR_FLAG; + msg.can_dlc = CAN_ERR_DLC; + + if (state & SF_MASK_BUSOFF) { + can_state = CAN_STATE_BUS_OFF; + msg.can_id |= CAN_ERR_BUSOFF; + state = STATE_BUSOFF; + } else if (state & SF_MASK_EPASSIVE) { + can_state = CAN_STATE_ERROR_PASSIVE; + msg.can_id |= CAN_ERR_CRTL; + msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE; + state = STATE_EPASSIVE; + } else { + can_state = CAN_STATE_ERROR_ACTIVE; + msg.can_id |= CAN_ERR_CRTL; + state = STATE_EACTIVE; + } + /* update DPRAM */ + iowrite8(state, &card->dpram[priv->index ? + DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]); + /* timestamp */ + tmp_u32 = le32_to_cpup((void *)ptr); + ptr += 4; + ktime = softing_raw2ktime(card, tmp_u32); + + ++netdev->stats.rx_errors; + /* update internal status */ + if (can_state != priv->can.state) { + priv->can.state = can_state; + if (can_state == CAN_STATE_ERROR_PASSIVE) + ++priv->can.can_stats.error_passive; + else if (can_state == CAN_STATE_BUS_OFF) { + /* this calls can_close_cleanup() */ + can_bus_off(netdev); + netif_stop_queue(netdev); + } + /* trigger socketcan */ + softing_netdev_rx(netdev, &msg, ktime); + } + + } else { + if (cmd & CMD_RTR) + msg.can_id |= CAN_RTR_FLAG; + msg.can_dlc = get_can_dlc(*ptr++); + if (cmd & CMD_XTD) { + msg.can_id |= CAN_EFF_FLAG; + msg.can_id |= le32_to_cpup((void *)ptr); + ptr += 4; + } else { + msg.can_id |= le16_to_cpup((void *)ptr); + ptr += 2; + } + /* timestamp */ + tmp_u32 = le32_to_cpup((void *)ptr); + ptr += 4; + ktime = softing_raw2ktime(card, tmp_u32); + if (!(msg.can_id & CAN_RTR_FLAG)) + memcpy(&msg.data[0], ptr, 8); + ptr += 8; + /* update socket */ + if (cmd & CMD_ACK) { + /* acknowledge, was tx msg */ + struct sk_buff *skb; + skb = priv->can.echo_skb[priv->tx.echo_get]; + if (skb) + skb->tstamp = ktime; + can_get_echo_skb(netdev, priv->tx.echo_get); + ++priv->tx.echo_get; + if (priv->tx.echo_get >= TX_ECHO_SKB_MAX) + priv->tx.echo_get = 0; + if (priv->tx.pending) + --priv->tx.pending; + if (card->tx.pending) + --card->tx.pending; + ++netdev->stats.tx_packets; + if (!(msg.can_id & CAN_RTR_FLAG)) + netdev->stats.tx_bytes += msg.can_dlc; + } else { + int ret; + + ret = softing_netdev_rx(netdev, &msg, ktime); + if (ret == NET_RX_SUCCESS) { + ++netdev->stats.rx_packets; + if (!(msg.can_id & CAN_RTR_FLAG)) + netdev->stats.rx_bytes += msg.can_dlc; + } else { + ++netdev->stats.rx_dropped; + } + } + } + ++cnt; + return cnt; +} + +/* + * real interrupt handler + */ +static irqreturn_t softing_irq_thread(int irq, void *dev_id) +{ + struct softing *card = (struct softing *)dev_id; + struct net_device *netdev; + struct softing_priv *priv; + int j, offset, work_done; + + work_done = 0; + spin_lock_bh(&card->spin); + while (softing_handle_1(card) > 0) { + ++card->irq.svc_count; + ++work_done; + } + spin_unlock_bh(&card->spin); + /* resume tx queue's */ + offset = card->tx.last_bus; + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + if (card->tx.pending >= TXMAX) + break; + netdev = card->net[(j + offset + 1) % card->pdat->nbus]; + if (!netdev) + continue; + priv = netdev_priv(netdev); + if (!canif_is_active(netdev)) + /* it makes no sense to wake dead busses */ + continue; + if (priv->tx.pending >= TX_ECHO_SKB_MAX) + continue; + ++work_done; + netif_wake_queue(netdev); + } + return work_done ? IRQ_HANDLED : IRQ_NONE; +} + +/* + * interrupt routines: + * schedule the 'real interrupt handler' + */ +static irqreturn_t softing_irq_v2(int irq, void *dev_id) +{ + struct softing *card = (struct softing *)dev_id; + uint8_t ir; + + ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]); + iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]); + return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE; +} + +static irqreturn_t softing_irq_v1(int irq, void *dev_id) +{ + struct softing *card = (struct softing *)dev_id; + uint8_t ir; + + ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]); + iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]); + return ir ? IRQ_WAKE_THREAD : IRQ_NONE; +} + +/* + * netdev/candev inter-operability + */ +static int softing_netdev_open(struct net_device *ndev) +{ + int ret; + + /* check or determine and set bittime */ + ret = open_candev(ndev); + if (!ret) + ret = softing_startstop(ndev, 1); + return ret; +} + +static int softing_netdev_stop(struct net_device *ndev) +{ + int ret; + + netif_stop_queue(ndev); + + /* softing cycle does close_candev() */ + ret = softing_startstop(ndev, 0); + return ret; +} + +static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode) +{ + int ret; + + switch (mode) { + case CAN_MODE_START: + /* softing_startstop does close_candev() */ + ret = softing_startstop(ndev, 1); + return ret; + case CAN_MODE_STOP: + case CAN_MODE_SLEEP: + return -EOPNOTSUPP; + } + return 0; +} + +/* + * Softing device management helpers + */ +int softing_enable_irq(struct softing *card, int enable) +{ + int ret; + + if (!card->irq.nr) { + return 0; + } else if (card->irq.requested && !enable) { + free_irq(card->irq.nr, card); + card->irq.requested = 0; + } else if (!card->irq.requested && enable) { + ret = request_threaded_irq(card->irq.nr, + (card->pdat->generation >= 2) ? + softing_irq_v2 : softing_irq_v1, + softing_irq_thread, IRQF_SHARED, + dev_name(&card->pdev->dev), card); + if (ret) { + dev_alert(&card->pdev->dev, + "request_threaded_irq(%u) failed\n", + card->irq.nr); + return ret; + } + card->irq.requested = 1; + } + return 0; +} + +static void softing_card_shutdown(struct softing *card) +{ + int fw_up = 0; + + if (mutex_lock_interruptible(&card->fw.lock)) + /* return -ERESTARTSYS */; + fw_up = card->fw.up; + card->fw.up = 0; + + if (card->irq.requested && card->irq.nr) { + free_irq(card->irq.nr, card); + card->irq.requested = 0; + } + if (fw_up) { + if (card->pdat->enable_irq) + card->pdat->enable_irq(card->pdev, 0); + softing_set_reset_dpram(card); + if (card->pdat->reset) + card->pdat->reset(card->pdev, 1); + } + mutex_unlock(&card->fw.lock); +} + +static __devinit int softing_card_boot(struct softing *card) +{ + int ret, j; + static const uint8_t stream[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }; + unsigned char back[sizeof(stream)]; + + if (mutex_lock_interruptible(&card->fw.lock)) + return -ERESTARTSYS; + if (card->fw.up) { + mutex_unlock(&card->fw.lock); + return 0; + } + /* reset board */ + if (card->pdat->enable_irq) + card->pdat->enable_irq(card->pdev, 1); + /* boot card */ + softing_set_reset_dpram(card); + if (card->pdat->reset) + card->pdat->reset(card->pdev, 1); + for (j = 0; (j + sizeof(stream)) < card->dpram_size; + j += sizeof(stream)) { + + memcpy_toio(&card->dpram[j], stream, sizeof(stream)); + /* flush IO cache */ + mb(); + memcpy_fromio(back, &card->dpram[j], sizeof(stream)); + + if (!memcmp(back, stream, sizeof(stream))) + continue; + /* memory is not equal */ + dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j); + ret = -EIO; + goto failed; + } + wmb(); + /* load boot firmware */ + ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram, + card->dpram_size, + card->pdat->boot.offs - card->pdat->boot.addr); + if (ret < 0) + goto failed; + /* load loader firmware */ + ret = softing_load_fw(card->pdat->load.fw, card, card->dpram, + card->dpram_size, + card->pdat->load.offs - card->pdat->load.addr); + if (ret < 0) + goto failed; + + if (card->pdat->reset) + card->pdat->reset(card->pdev, 0); + softing_clr_reset_dpram(card); + ret = softing_bootloader_command(card, 0, "card boot"); + if (ret < 0) + goto failed; + ret = softing_load_app_fw(card->pdat->app.fw, card); + if (ret < 0) + goto failed; + + ret = softing_chip_poweron(card); + if (ret < 0) + goto failed; + + card->fw.up = 1; + mutex_unlock(&card->fw.lock); + return 0; +failed: + card->fw.up = 0; + if (card->pdat->enable_irq) + card->pdat->enable_irq(card->pdev, 0); + softing_set_reset_dpram(card); + if (card->pdat->reset) + card->pdat->reset(card->pdev, 1); + mutex_unlock(&card->fw.lock); + return ret; +} + +/* + * netdev sysfs + */ +static ssize_t show_channel(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct net_device *ndev = to_net_dev(dev); + struct softing_priv *priv = netdev2softing(ndev); + + return sprintf(buf, "%i\n", priv->index); +} + +static ssize_t show_chip(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct net_device *ndev = to_net_dev(dev); + struct softing_priv *priv = netdev2softing(ndev); + + return sprintf(buf, "%i\n", priv->chip); +} + +static ssize_t show_output(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct net_device *ndev = to_net_dev(dev); + struct softing_priv *priv = netdev2softing(ndev); + + return sprintf(buf, "0x%02x\n", priv->output); +} + +static ssize_t store_output(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct net_device *ndev = to_net_dev(dev); + struct softing_priv *priv = netdev2softing(ndev); + struct softing *card = priv->card; + unsigned long val; + int ret; + + ret = strict_strtoul(buf, 0, &val); + if (ret < 0) + return ret; + val &= 0xFF; + + ret = mutex_lock_interruptible(&card->fw.lock); + if (ret) + return -ERESTARTSYS; + if (netif_running(ndev)) { + mutex_unlock(&card->fw.lock); + return -EBUSY; + } + priv->output = val; + mutex_unlock(&card->fw.lock); + return count; +} + +static const DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL); +static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL); +static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output); + +static const struct attribute *const netdev_sysfs_attrs[] = { + &dev_attr_channel.attr, + &dev_attr_chip.attr, + &dev_attr_output.attr, + NULL, +}; +static const struct attribute_group netdev_sysfs_group = { + .name = NULL, + .attrs = (struct attribute **)netdev_sysfs_attrs, +}; + +static const struct net_device_ops softing_netdev_ops = { + .ndo_open = softing_netdev_open, + .ndo_stop = softing_netdev_stop, + .ndo_start_xmit = softing_netdev_start_xmit, +}; + +static const struct can_bittiming_const softing_btr_const = { + .tseg1_min = 1, + .tseg1_max = 16, + .tseg2_min = 1, + .tseg2_max = 8, + .sjw_max = 4, /* overruled */ + .brp_min = 1, + .brp_max = 32, /* overruled */ + .brp_inc = 1, +}; + + +static __devinit struct net_device *softing_netdev_create(struct softing *card, + uint16_t chip_id) +{ + struct net_device *netdev; + struct softing_priv *priv; + + netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX); + if (!netdev) { + dev_alert(&card->pdev->dev, "alloc_candev failed\n"); + return NULL; + } + priv = netdev_priv(netdev); + priv->netdev = netdev; + priv->card = card; + memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const)); + priv->btr_const.brp_max = card->pdat->max_brp; + priv->btr_const.sjw_max = card->pdat->max_sjw; + priv->can.bittiming_const = &priv->btr_const; + priv->can.clock.freq = 8000000; + priv->chip = chip_id; + priv->output = softing_default_output(netdev); + SET_NETDEV_DEV(netdev, &card->pdev->dev); + + netdev->flags |= IFF_ECHO; + netdev->netdev_ops = &softing_netdev_ops; + priv->can.do_set_mode = softing_candev_set_mode; + priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; + + return netdev; +} + +static __devinit int softing_netdev_register(struct net_device *netdev) +{ + int ret; + + netdev->sysfs_groups[0] = &netdev_sysfs_group; + ret = register_candev(netdev); + if (ret) { + dev_alert(&netdev->dev, "register failed\n"); + return ret; + } + return 0; +} + +static void softing_netdev_cleanup(struct net_device *netdev) +{ + unregister_candev(netdev); + free_candev(netdev); +} + +/* + * sysfs for Platform device + */ +#define DEV_ATTR_RO(name, member) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct softing *card = platform_get_drvdata(to_platform_device(dev)); \ + return sprintf(buf, "%u\n", card->member); \ +} \ +static DEVICE_ATTR(name, 0444, show_##name, NULL) + +#define DEV_ATTR_RO_STR(name, member) \ +static ssize_t show_##name(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct softing *card = platform_get_drvdata(to_platform_device(dev)); \ + return sprintf(buf, "%s\n", card->member); \ +} \ +static DEVICE_ATTR(name, 0444, show_##name, NULL) + +DEV_ATTR_RO(serial, id.serial); +DEV_ATTR_RO_STR(firmware, pdat->app.fw); +DEV_ATTR_RO(firmware_version, id.fw_version); +DEV_ATTR_RO_STR(hardware, pdat->name); +DEV_ATTR_RO(hardware_version, id.hw_version); +DEV_ATTR_RO(license, id.license); +DEV_ATTR_RO(frequency, id.freq); +DEV_ATTR_RO(txpending, tx.pending); + +static struct attribute *softing_pdev_attrs[] = { + &dev_attr_serial.attr, + &dev_attr_firmware.attr, + &dev_attr_firmware_version.attr, + &dev_attr_hardware.attr, + &dev_attr_hardware_version.attr, + &dev_attr_license.attr, + &dev_attr_frequency.attr, + &dev_attr_txpending.attr, + NULL, +}; + +static const struct attribute_group softing_pdev_group = { + .name = NULL, + .attrs = softing_pdev_attrs, +}; + +/* + * platform driver + */ +static __devexit int softing_pdev_remove(struct platform_device *pdev) +{ + struct softing *card = platform_get_drvdata(pdev); + int j; + + /* first, disable card*/ + softing_card_shutdown(card); + + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + if (!card->net[j]) + continue; + softing_netdev_cleanup(card->net[j]); + card->net[j] = NULL; + } + sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); + + iounmap(card->dpram); + kfree(card); + return 0; +} + +static __devinit int softing_pdev_probe(struct platform_device *pdev) +{ + const struct softing_platform_data *pdat = pdev->dev.platform_data; + struct softing *card; + struct net_device *netdev; + struct softing_priv *priv; + struct resource *pres; + int ret; + int j; + + if (!pdat) { + dev_warn(&pdev->dev, "no platform data\n"); + return -EINVAL; + } + if (pdat->nbus > ARRAY_SIZE(card->net)) { + dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus); + return -EINVAL; + } + + card = kzalloc(sizeof(*card), GFP_KERNEL); + if (!card) + return -ENOMEM; + card->pdat = pdat; + card->pdev = pdev; + platform_set_drvdata(pdev, card); + mutex_init(&card->fw.lock); + spin_lock_init(&card->spin); + + ret = -EINVAL; + pres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!pres) + goto platform_resource_failed;; + card->dpram_phys = pres->start; + card->dpram_size = pres->end - pres->start + 1; + card->dpram = ioremap_nocache(card->dpram_phys, card->dpram_size); + if (!card->dpram) { + dev_alert(&card->pdev->dev, "dpram ioremap failed\n"); + goto ioremap_failed; + } + + pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (pres) + card->irq.nr = pres->start; + + /* reset card */ + ret = softing_card_boot(card); + if (ret < 0) { + dev_alert(&pdev->dev, "failed to boot\n"); + goto boot_failed; + } + + /* only now, the chip's are known */ + card->id.freq = card->pdat->freq; + + ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group); + if (ret < 0) { + dev_alert(&card->pdev->dev, "sysfs failed\n"); + goto sysfs_failed; + } + + ret = -ENOMEM; + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + card->net[j] = netdev = + softing_netdev_create(card, card->id.chip[j]); + if (!netdev) { + dev_alert(&pdev->dev, "failed to make can[%i]", j); + goto netdev_failed; + } + priv = netdev_priv(card->net[j]); + priv->index = j; + ret = softing_netdev_register(netdev); + if (ret) { + free_candev(netdev); + card->net[j] = NULL; + dev_alert(&card->pdev->dev, + "failed to register can[%i]\n", j); + goto netdev_failed; + } + } + dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name); + return 0; + +netdev_failed: + for (j = 0; j < ARRAY_SIZE(card->net); ++j) { + if (!card->net[j]) + continue; + softing_netdev_cleanup(card->net[j]); + } + sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group); +sysfs_failed: + softing_card_shutdown(card); +boot_failed: + iounmap(card->dpram); +ioremap_failed: +platform_resource_failed: + kfree(card); + return ret; +} + +static struct platform_driver softing_driver = { + .driver = { + .name = "softing", + .owner = THIS_MODULE, + }, + .probe = softing_pdev_probe, + .remove = __devexit_p(softing_pdev_remove), +}; + +MODULE_ALIAS("platform:softing"); + +static int __init softing_start(void) +{ + return platform_driver_register(&softing_driver); +} + +static void __exit softing_stop(void) +{ + platform_driver_unregister(&softing_driver); +} + +module_init(softing_start); +module_exit(softing_stop); + +MODULE_DESCRIPTION("Softing DPRAM CAN driver"); +MODULE_AUTHOR("Kurt Van Dijck <kurt.van.dijck@eia.be>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/net/can/softing/softing_platform.h b/drivers/net/can/softing/softing_platform.h new file mode 100644 index 0000000..ebbf698 --- /dev/null +++ b/drivers/net/can/softing/softing_platform.h @@ -0,0 +1,40 @@ + +#include <linux/platform_device.h> + +#ifndef _SOFTING_DEVICE_H_ +#define _SOFTING_DEVICE_H_ + +/* softing firmware directory prefix */ +#define fw_dir "softing-4.6/" + +struct softing_platform_data { + unsigned int manf; + unsigned int prod; + /* + * generation + * 1st with NEC or SJA1000 + * 8bit, exclusive interrupt, ... + * 2nd only SJA1000 + * 16bit, shared interrupt + */ + int generation; + int nbus; /* # busses on device */ + unsigned int freq; /* operating frequency in Hz */ + unsigned int max_brp; + unsigned int max_sjw; + unsigned long dpram_size; + const char *name; + struct { + unsigned long offs; + unsigned long addr; + const char *fw; + } boot, load, app; + /* + * reset() function + * bring pdev in or out of reset, depending on value + */ + int (*reset)(struct platform_device *pdev, int value); + int (*enable_irq)(struct platform_device *pdev, int value); +}; + +#endif diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index 059c1ee..ec35d45 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -2710,6 +2710,8 @@ static int cxgb_open(struct net_device *dev) struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; + netif_carrier_off(dev); + if (!(adapter->flags & FULL_INIT_DONE)) { err = cxgb_up(adapter); if (err < 0) @@ -3661,7 +3663,6 @@ static int __devinit init_one(struct pci_dev *pdev, pi->xact_addr_filt = -1; pi->rx_offload = RX_CSO; pi->port_id = i; - netif_carrier_off(netdev); netdev->irq = pdev->irq; netdev->features |= NETIF_F_SG | TSO_FLAGS; diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index dda7098..dc29348 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig @@ -31,7 +31,7 @@ source "drivers/pci/pcie/aer/Kconfig" # PCI Express ASPM # config PCIEASPM - bool "PCI Express ASPM control" if EMBEDDED + bool "PCI Express ASPM control" if EXPERT depends on PCI && PCIEPORTBUS default y help diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index de886f3..6e318ce 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -69,7 +69,7 @@ comment "PC-card bridges" config YENTA tristate "CardBus yenta-compatible bridge support" depends on PCI - select CARDBUS if !EMBEDDED + select CARDBUS if !EXPERT select PCCARD_NONSTATIC if PCMCIA != n ---help--- This option enables support for CardBus host bridges. Virtually @@ -84,27 +84,27 @@ config YENTA config YENTA_O2 default y - bool "Special initialization for O2Micro bridges" if EMBEDDED + bool "Special initialization for O2Micro bridges" if EXPERT depends on YENTA config YENTA_RICOH default y - bool "Special initialization for Ricoh bridges" if EMBEDDED + bool "Special initialization for Ricoh bridges" if EXPERT depends on YENTA config YENTA_TI default y - bool "Special initialization for TI and EnE bridges" if EMBEDDED + bool "Special initialization for TI and EnE bridges" if EXPERT depends on YENTA config YENTA_ENE_TUNE default y - bool "Auto-tune EnE bridges for CB cards" if EMBEDDED + bool "Auto-tune EnE bridges for CB cards" if EXPERT depends on YENTA_TI && CARDBUS config YENTA_TOSHIBA default y - bool "Special initialization for Toshiba ToPIC bridges" if EMBEDDED + bool "Special initialization for Toshiba ToPIC bridges" if EXPERT depends on YENTA config PD6729 diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index 467e82b..a50391b 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c @@ -943,6 +943,8 @@ static int rio_enum_complete(struct rio_mport *port) * @port: Master port to send transactions * @destid: Current destination ID in network * @hopcount: Number of hops into the network + * @prev: previous rio_dev + * @prev_port: previous port number * * Recursively discovers a RIO network. Transactions are sent via the * master port passed in @port. diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 4941cad..cdd9719 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -97,18 +97,6 @@ config RTC_INTF_DEV If unsure, say Y. -config RTC_INTF_DEV_UIE_EMUL - bool "RTC UIE emulation on dev interface" - depends on RTC_INTF_DEV - help - Provides an emulation for RTC_UIE if the underlying rtc chip - driver does not expose RTC_UIE ioctls. Those requests generate - once-per-second update interrupts, used for synchronization. - - The emulation code will read the time from the hardware - clock several times per second, please enable this option - only if you know that you really need it. - config RTC_DRV_TEST tristate "Test driver/device" help diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 90384b9..925006d 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -16,6 +16,9 @@ #include <linux/log2.h> #include <linux/workqueue.h> +static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer); +static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer); + static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) { int err; @@ -120,12 +123,18 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; - alarm->enabled = rtc->aie_timer.enabled; - if (alarm->enabled) + if (rtc->ops == NULL) + err = -ENODEV; + else if (!rtc->ops->read_alarm) + err = -EINVAL; + else { + memset(alarm, 0, sizeof(struct rtc_wkalrm)); + alarm->enabled = rtc->aie_timer.enabled; alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires); + } mutex_unlock(&rtc->ops_lock); - return 0; + return err; } EXPORT_SYMBOL_GPL(rtc_read_alarm); @@ -175,16 +184,14 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) return err; if (rtc->aie_timer.enabled) { 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; - rtc_timer_enqueue(rtc, &rtc->aie_timer); + err = rtc_timer_enqueue(rtc, &rtc->aie_timer); } mutex_unlock(&rtc->ops_lock); - return 0; + return err; } EXPORT_SYMBOL_GPL(rtc_set_alarm); @@ -195,15 +202,15 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) return err; if (rtc->aie_timer.enabled != enabled) { - if (enabled) { - rtc->aie_timer.enabled = 1; - rtc_timer_enqueue(rtc, &rtc->aie_timer); - } else { + if (enabled) + err = rtc_timer_enqueue(rtc, &rtc->aie_timer); + else rtc_timer_remove(rtc, &rtc->aie_timer); - rtc->aie_timer.enabled = 0; - } } + if (err) + return err; + if (!rtc->ops) err = -ENODEV; else if (!rtc->ops->alarm_irq_enable) @@ -235,12 +242,9 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) 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; - rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); - } else { + err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); + } else rtc_timer_remove(rtc, &rtc->uie_rtctimer); - rtc->uie_rtctimer.enabled = 0; - } out: mutex_unlock(&rtc->ops_lock); @@ -488,10 +492,13 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq); * Enqueues a timer onto the rtc devices timerqueue and sets * the next alarm event appropriately. * + * Sets the enabled bit on the added timer. + * * Must hold ops_lock for proper serialization of timerqueue */ -void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) +static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) { + timer->enabled = 1; timerqueue_add(&rtc->timerqueue, &timer->node); if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { struct rtc_wkalrm alarm; @@ -501,7 +508,13 @@ void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) err = __rtc_set_alarm(rtc, &alarm); if (err == -ETIME) schedule_work(&rtc->irqwork); + else if (err) { + timerqueue_del(&rtc->timerqueue, &timer->node); + timer->enabled = 0; + return err; + } } + return 0; } /** @@ -512,13 +525,15 @@ void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) * Removes a timer onto the rtc devices timerqueue and sets * the next alarm event appropriately. * + * Clears the enabled bit on the removed timer. + * * Must hold ops_lock for proper serialization of timerqueue */ -void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) +static 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); - + timer->enabled = 0; if (next == &timer->node) { struct rtc_wkalrm alarm; int err; @@ -626,8 +641,7 @@ int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer, timer->node.expires = expires; timer->period = period; - timer->enabled = 1; - rtc_timer_enqueue(rtc, timer); + ret = rtc_timer_enqueue(rtc, timer); mutex_unlock(&rtc->ops_lock); return ret; @@ -645,7 +659,6 @@ int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer) mutex_lock(&rtc->ops_lock); if (timer->enabled) rtc_timer_remove(rtc, timer); - timer->enabled = 0; mutex_unlock(&rtc->ops_lock); return ret; } diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index 2d8cc45..42cdaa9 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig @@ -82,7 +82,7 @@ config SSB_SDIOHOST config SSB_SILENT bool "No SSB kernel messages" - depends on SSB && EMBEDDED + depends on SSB && EXPERT help This option turns off all Sonics Silicon Backplane printks. Note that you won't be able to identify problems, once diff --git a/drivers/staging/lirc/TODO.lirc_zilog b/drivers/staging/lirc/TODO.lirc_zilog index 6aa312d..2d0263f 100644 --- a/drivers/staging/lirc/TODO.lirc_zilog +++ b/drivers/staging/lirc/TODO.lirc_zilog @@ -1,13 +1,37 @@ -The binding between hdpvr and lirc_zilog is currently disabled, +1. Both ir-kbd-i2c and lirc_zilog provide support for RX events. +The 'tx_only' lirc_zilog module parameter will allow ir-kbd-i2c +and lirc_zilog to coexist in the kernel, if the user requires such a set-up. +However the IR unit will not work well without coordination between the +two modules. A shared mutex, for transceiver access locking, needs to be +supplied by bridge drivers, in struct IR_i2_init_data, to both ir-kbd-i2c +and lirc_zilog, before they will coexist usefully. This should be fixed +before moving out of staging. + +2. References and locking need careful examination. For cx18 and ivtv PCI +cards, which are not easily "hot unplugged", the imperfect state of reference +counting and locking is acceptable if not correct. For USB connected units +like HD PVR, PVR USB2, HVR-1900, and HVR1950, the likelyhood of an Ooops on +unplug is probably great. Proper reference counting and locking needs to be +implemented before this module is moved out of staging. + +3. The binding between hdpvr and lirc_zilog is currently disabled, due to an OOPS reported a few years ago when both the hdpvr and cx18 drivers were loaded in his system. More details can be seen at: http://www.mail-archive.com/linux-media@vger.kernel.org/msg09163.html More tests need to be done, in order to fix the reported issue. -There's a conflict between ir-kbd-i2c: Both provide support for RX events. -Such conflict needs to be fixed, before moving it out of staging. +4. In addition to providing a shared mutex for transceiver access +locking, bridge drivers, if able, should provide a chip reset() callback +to lirc_zilog via struct IR_i2c_init_data. cx18 and ivtv already have routines +to perform Z8 chip resets via GPIO manipulations. This will allow lirc_zilog +to bring the chip back to normal when it hangs, in the same places the +original lirc_pvr150 driver code does. This is not strictly needed, so it +is not required to move lirc_zilog out of staging. + +5. Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed +and installed on Hauppauge products. When working on either module, developers +must consider at least the following bridge drivers which mention an IR Rx unit +at address 0x71 (indicative of a Z8): -The way I2C probe works, it will try to register the driver twice, one -for RX and another for TX. The logic needs to be fixed to avoid such -issue. + ivtv cx18 hdpvr pvrusb2 bt8xx cx88 saa7134 diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c index 0da6b95..235cab0 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 929ae57..5938616 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 dfd2c44..3a9c098 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 998485e..925eabe 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 9bcf149..1c3099b 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 c553ab6..76be7b8 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; } diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c index ad29bb1..3fe5f41 100644 --- a/drivers/staging/lirc/lirc_zilog.c +++ b/drivers/staging/lirc/lirc_zilog.c @@ -20,6 +20,9 @@ * * parts are cut&pasted from the lirc_i2c.c driver * + * Numerous changes updating lirc_zilog.c in kernel 2.6.38 and later are + * Copyright (C) 2011 Andy Walls <awalls@md.metrocast.net> + * * 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 @@ -60,38 +63,44 @@ #include <media/lirc_dev.h> #include <media/lirc.h> -struct IR { - struct lirc_driver l; - - /* Device info */ - struct mutex ir_lock; - int open; - bool is_hdpvr; - +struct IR_rx { /* RX device */ - struct i2c_client c_rx; - int have_rx; + struct i2c_client *c; /* RX device buffer & lock */ struct lirc_buffer buf; struct mutex buf_lock; /* RX polling thread data */ - struct completion *t_notify; - struct completion *t_notify2; - int shutdown; struct task_struct *task; /* RX read data */ unsigned char b[3]; + bool hdpvr_data_fmt; +}; +struct IR_tx { /* TX device */ - struct i2c_client c_tx; + struct i2c_client *c; + + /* TX additional actions needed */ int need_boot; - int have_tx; + bool post_tx_ready_poll; +}; + +struct IR { + struct lirc_driver l; + + struct mutex ir_lock; + int open; + + struct i2c_adapter *adapter; + struct IR_rx *rx; + struct IR_tx *tx; }; /* Minor -> data mapping */ +static struct mutex ir_devices_lock; static struct IR *ir_devices[MAX_IRCTL_DEVICES]; /* Block size for IR transmitter */ @@ -124,14 +133,11 @@ static struct mutex tx_data_lock; #define zilog_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, \ ## args) #define zilog_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) - -#define ZILOG_HAUPPAUGE_IR_RX_NAME "Zilog/Hauppauge IR RX" -#define ZILOG_HAUPPAUGE_IR_TX_NAME "Zilog/Hauppauge IR TX" +#define zilog_info(s, args...) printk(KERN_INFO KBUILD_MODNAME ": " s, ## args) /* module parameters */ static int debug; /* debug output */ -static int disable_rx; /* disable RX device */ -static int disable_tx; /* disable TX device */ +static int tx_only; /* only handle the IR Tx function */ static int minor = -1; /* minor number */ #define dprintk(fmt, args...) \ @@ -150,8 +156,12 @@ static int add_to_buf(struct IR *ir) int ret; int failures = 0; unsigned char sendbuf[1] = { 0 }; + struct IR_rx *rx = ir->rx; - if (lirc_buffer_full(&ir->buf)) { + if (rx == NULL) + return -ENXIO; + + if (lirc_buffer_full(&rx->buf)) { dprintk("buffer overflow\n"); return -EOVERFLOW; } @@ -161,17 +171,25 @@ static int add_to_buf(struct IR *ir) * data and we have space */ do { + if (kthread_should_stop()) + return -ENODATA; + /* * Lock i2c bus for the duration. RX/TX chips interfere so * this is worth it */ mutex_lock(&ir->ir_lock); + if (kthread_should_stop()) { + mutex_unlock(&ir->ir_lock); + return -ENODATA; + } + /* * Send random "poll command" (?) Windows driver does this * and it is a good point to detect chip failure. */ - ret = i2c_master_send(&ir->c_rx, sendbuf, 1); + ret = i2c_master_send(rx->c, sendbuf, 1); if (ret != 1) { zilog_error("i2c_master_send failed with %d\n", ret); if (failures >= 3) { @@ -186,45 +204,53 @@ static int add_to_buf(struct IR *ir) "trying reset\n"); set_current_state(TASK_UNINTERRUPTIBLE); + if (kthread_should_stop()) { + mutex_unlock(&ir->ir_lock); + return -ENODATA; + } schedule_timeout((100 * HZ + 999) / 1000); - ir->need_boot = 1; + ir->tx->need_boot = 1; ++failures; mutex_unlock(&ir->ir_lock); continue; } - ret = i2c_master_recv(&ir->c_rx, keybuf, sizeof(keybuf)); + if (kthread_should_stop()) { + mutex_unlock(&ir->ir_lock); + return -ENODATA; + } + ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf)); mutex_unlock(&ir->ir_lock); if (ret != sizeof(keybuf)) { zilog_error("i2c_master_recv failed with %d -- " "keeping last read buffer\n", ret); } else { - ir->b[0] = keybuf[3]; - ir->b[1] = keybuf[4]; - ir->b[2] = keybuf[5]; - dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]); + rx->b[0] = keybuf[3]; + rx->b[1] = keybuf[4]; + rx->b[2] = keybuf[5]; + dprintk("key (0x%02x/0x%02x)\n", rx->b[0], rx->b[1]); } /* key pressed ? */ - if (ir->is_hdpvr) { + if (rx->hdpvr_data_fmt) { if (got_data && (keybuf[0] == 0x80)) return 0; else if (got_data && (keybuf[0] == 0x00)) return -ENODATA; - } else if ((ir->b[0] & 0x80) == 0) + } else if ((rx->b[0] & 0x80) == 0) return got_data ? 0 : -ENODATA; /* look what we have */ - code = (((__u16)ir->b[0] & 0x7f) << 6) | (ir->b[1] >> 2); + code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2); codes[0] = (code >> 8) & 0xff; codes[1] = code & 0xff; /* return it */ - lirc_buffer_write(&ir->buf, codes); + lirc_buffer_write(&rx->buf, codes); ++got_data; - } while (!lirc_buffer_full(&ir->buf)); + } while (!lirc_buffer_full(&rx->buf)); return 0; } @@ -242,46 +268,35 @@ static int add_to_buf(struct IR *ir) static int lirc_thread(void *arg) { struct IR *ir = arg; - - if (ir->t_notify != NULL) - complete(ir->t_notify); + struct IR_rx *rx = ir->rx; dprintk("poll thread started\n"); - do { - if (ir->open) { - set_current_state(TASK_INTERRUPTIBLE); + while (!kthread_should_stop()) { + set_current_state(TASK_INTERRUPTIBLE); - /* - * This is ~113*2 + 24 + jitter (2*repeat gap + - * code length). We use this interval as the chip - * resets every time you poll it (bad!). This is - * therefore just sufficient to catch all of the - * button presses. It makes the remote much more - * responsive. You can see the difference by - * running irw and holding down a button. With - * 100ms, the old polling interval, you'll notice - * breaks in the repeat sequence corresponding to - * lost keypresses. - */ - schedule_timeout((260 * HZ) / 1000); - if (ir->shutdown) - break; - if (!add_to_buf(ir)) - wake_up_interruptible(&ir->buf.wait_poll); - } else { - /* if device not opened so we can sleep half a second */ - set_current_state(TASK_INTERRUPTIBLE); + /* if device not opened, we can sleep half a second */ + if (!ir->open) { schedule_timeout(HZ/2); + continue; } - } while (!ir->shutdown); - - if (ir->t_notify2 != NULL) - wait_for_completion(ir->t_notify2); - ir->task = NULL; - if (ir->t_notify != NULL) - complete(ir->t_notify); + /* + * This is ~113*2 + 24 + jitter (2*repeat gap + code length). + * We use this interval as the chip resets every time you poll + * it (bad!). This is therefore just sufficient to catch all + * of the button presses. It makes the remote much more + * responsive. You can see the difference by running irw and + * holding down a button. With 100ms, the old polling + * interval, you'll notice breaks in the repeat sequence + * corresponding to lost keypresses. + */ + schedule_timeout((260 * HZ) / 1000); + if (kthread_should_stop()) + break; + if (!add_to_buf(ir)) + wake_up_interruptible(&rx->buf.wait_poll); + } dprintk("poll thread ended\n"); return 0; @@ -299,10 +314,10 @@ static int set_use_inc(void *data) * this is completely broken code. lirc_unregister_driver() * must be possible even when the device is open */ - if (ir->c_rx.addr) - i2c_use_client(&ir->c_rx); - if (ir->c_tx.addr) - i2c_use_client(&ir->c_tx); + if (ir->rx != NULL) + i2c_use_client(ir->rx->c); + if (ir->tx != NULL) + i2c_use_client(ir->tx->c); return 0; } @@ -311,10 +326,10 @@ static void set_use_dec(void *data) { struct IR *ir = data; - if (ir->c_rx.addr) - i2c_release_client(&ir->c_rx); - if (ir->c_tx.addr) - i2c_release_client(&ir->c_tx); + if (ir->rx) + i2c_release_client(ir->rx->c); + if (ir->tx) + i2c_release_client(ir->tx->c); if (ir->l.owner != NULL) module_put(ir->l.owner); } @@ -453,7 +468,7 @@ corrupt: } /* send a block of data to the IR TX device */ -static int send_data_block(struct IR *ir, unsigned char *data_block) +static int send_data_block(struct IR_tx *tx, unsigned char *data_block) { int i, j, ret; unsigned char buf[5]; @@ -467,7 +482,7 @@ static int send_data_block(struct IR *ir, unsigned char *data_block) buf[1 + j] = data_block[i + j]; dprintk("%02x %02x %02x %02x %02x", buf[0], buf[1], buf[2], buf[3], buf[4]); - ret = i2c_master_send(&ir->c_tx, buf, tosend + 1); + ret = i2c_master_send(tx->c, buf, tosend + 1); if (ret != tosend + 1) { zilog_error("i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; @@ -478,32 +493,32 @@ static int send_data_block(struct IR *ir, unsigned char *data_block) } /* send boot data to the IR TX device */ -static int send_boot_data(struct IR *ir) +static int send_boot_data(struct IR_tx *tx) { int ret; unsigned char buf[4]; /* send the boot block */ - ret = send_data_block(ir, tx_data->boot_data); + ret = send_data_block(tx, tx_data->boot_data); if (ret != 0) return ret; /* kick it off? */ buf[0] = 0x00; buf[1] = 0x20; - ret = i2c_master_send(&ir->c_tx, buf, 2); + ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { zilog_error("i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } - ret = i2c_master_send(&ir->c_tx, buf, 1); + ret = i2c_master_send(tx->c, buf, 1); if (ret != 1) { zilog_error("i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } /* Here comes the firmware version... (hopefully) */ - ret = i2c_master_recv(&ir->c_tx, buf, 4); + ret = i2c_master_recv(tx->c, buf, 4); if (ret != 4) { zilog_error("i2c_master_recv failed with %d\n", ret); return 0; @@ -543,7 +558,7 @@ static void fw_unload(void) } /* load "firmware" for the IR TX device */ -static int fw_load(struct IR *ir) +static int fw_load(struct IR_tx *tx) { int ret; unsigned int i; @@ -558,7 +573,7 @@ static int fw_load(struct IR *ir) } /* Request codeset data file */ - ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &ir->c_tx.dev); + ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &tx->c->dev); if (ret != 0) { zilog_error("firmware haup-ir-blaster.bin not available " "(%d)\n", ret); @@ -685,20 +700,20 @@ out: } /* initialise the IR TX device */ -static int tx_init(struct IR *ir) +static int tx_init(struct IR_tx *tx) { int ret; /* Load 'firmware' */ - ret = fw_load(ir); + ret = fw_load(tx); if (ret != 0) return ret; /* Send boot block */ - ret = send_boot_data(ir); + ret = send_boot_data(tx); if (ret != 0) return ret; - ir->need_boot = 0; + tx->need_boot = 0; /* Looks good */ return 0; @@ -714,20 +729,20 @@ static loff_t lseek(struct file *filep, loff_t offset, int orig) static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) { struct IR *ir = filep->private_data; - unsigned char buf[ir->buf.chunk_size]; + struct IR_rx *rx = ir->rx; int ret = 0, written = 0; DECLARE_WAITQUEUE(wait, current); dprintk("read called\n"); - if (ir->c_rx.addr == 0) + if (rx == NULL) return -ENODEV; - if (mutex_lock_interruptible(&ir->buf_lock)) + if (mutex_lock_interruptible(&rx->buf_lock)) return -ERESTARTSYS; - if (n % ir->buf.chunk_size) { + if (n % rx->buf.chunk_size) { dprintk("read result = -EINVAL\n"); - mutex_unlock(&ir->buf_lock); + mutex_unlock(&rx->buf_lock); return -EINVAL; } @@ -736,7 +751,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) * to avoid losing scan code (in case when queue is awaken somewhere * between while condition checking and scheduling) */ - add_wait_queue(&ir->buf.wait_poll, &wait); + add_wait_queue(&rx->buf.wait_poll, &wait); set_current_state(TASK_INTERRUPTIBLE); /* @@ -744,7 +759,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) * mode and 'copy_to_user' is happy, wait for data. */ while (written < n && ret == 0) { - if (lirc_buffer_empty(&ir->buf)) { + if (lirc_buffer_empty(&rx->buf)) { /* * According to the read(2) man page, 'written' can be * returned as less than 'n', instead of blocking @@ -764,16 +779,17 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) schedule(); set_current_state(TASK_INTERRUPTIBLE); } else { - lirc_buffer_read(&ir->buf, buf); + unsigned char buf[rx->buf.chunk_size]; + lirc_buffer_read(&rx->buf, buf); ret = copy_to_user((void *)outbuf+written, buf, - ir->buf.chunk_size); - written += ir->buf.chunk_size; + rx->buf.chunk_size); + written += rx->buf.chunk_size; } } - remove_wait_queue(&ir->buf.wait_poll, &wait); + remove_wait_queue(&rx->buf.wait_poll, &wait); set_current_state(TASK_RUNNING); - mutex_unlock(&ir->buf_lock); + mutex_unlock(&rx->buf_lock); dprintk("read result = %s (%d)\n", ret ? "-EFAULT" : "OK", ret); @@ -782,7 +798,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) } /* send a keypress to the IR TX device */ -static int send_code(struct IR *ir, unsigned int code, unsigned int key) +static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key) { unsigned char data_block[TX_BLOCK_SIZE]; unsigned char buf[2]; @@ -799,26 +815,26 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) return ret; /* Send the data block */ - ret = send_data_block(ir, data_block); + ret = send_data_block(tx, data_block); if (ret != 0) return ret; /* Send data block length? */ buf[0] = 0x00; buf[1] = 0x40; - ret = i2c_master_send(&ir->c_tx, buf, 2); + ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { zilog_error("i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } - ret = i2c_master_send(&ir->c_tx, buf, 1); + ret = i2c_master_send(tx->c, buf, 1); if (ret != 1) { zilog_error("i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; } /* Send finished download? */ - ret = i2c_master_recv(&ir->c_tx, buf, 1); + ret = i2c_master_recv(tx->c, buf, 1); if (ret != 1) { zilog_error("i2c_master_recv failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; @@ -832,7 +848,7 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) /* Send prepare command? */ buf[0] = 0x00; buf[1] = 0x80; - ret = i2c_master_send(&ir->c_tx, buf, 2); + ret = i2c_master_send(tx->c, buf, 2); if (ret != 2) { zilog_error("i2c_master_send failed with %d\n", ret); return ret < 0 ? ret : -EFAULT; @@ -843,7 +859,7 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) * last i2c_master_recv always fails with a -5, so for now, we're * going to skip this whole mess and say we're done on the HD PVR */ - if (ir->is_hdpvr) { + if (!tx->post_tx_ready_poll) { dprintk("sent code %u, key %u\n", code, key); return 0; } @@ -857,7 +873,7 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) for (i = 0; i < 20; ++i) { set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((50 * HZ + 999) / 1000); - ret = i2c_master_send(&ir->c_tx, buf, 1); + ret = i2c_master_send(tx->c, buf, 1); if (ret == 1) break; dprintk("NAK expected: i2c_master_send " @@ -870,7 +886,7 @@ static int send_code(struct IR *ir, unsigned int code, unsigned int key) } /* Seems to be an 'ok' response */ - i = i2c_master_recv(&ir->c_tx, buf, 1); + i = i2c_master_recv(tx->c, buf, 1); if (i != 1) { zilog_error("i2c_master_recv failed with %d\n", ret); return -EFAULT; @@ -895,10 +911,11 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, loff_t *ppos) { struct IR *ir = filep->private_data; + struct IR_tx *tx = ir->tx; size_t i; int failures = 0; - if (ir->c_tx.addr == 0) + if (tx == NULL) return -ENODEV; /* Validate user parameters */ @@ -919,15 +936,15 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, } /* Send boot data first if required */ - if (ir->need_boot == 1) { - ret = send_boot_data(ir); + if (tx->need_boot == 1) { + ret = send_boot_data(tx); if (ret == 0) - ir->need_boot = 0; + tx->need_boot = 0; } /* Send the code */ if (ret == 0) { - ret = send_code(ir, (unsigned)command >> 16, + ret = send_code(tx, (unsigned)command >> 16, (unsigned)command & 0xFFFF); if (ret == -EPROTO) { mutex_unlock(&ir->ir_lock); @@ -952,7 +969,7 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, } set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((100 * HZ + 999) / 1000); - ir->need_boot = 1; + tx->need_boot = 1; ++failures; } else i += sizeof(int); @@ -969,22 +986,23 @@ static ssize_t write(struct file *filep, const char *buf, size_t n, static unsigned int poll(struct file *filep, poll_table *wait) { struct IR *ir = filep->private_data; + struct IR_rx *rx = ir->rx; unsigned int ret; dprintk("poll called\n"); - if (ir->c_rx.addr == 0) + if (rx == NULL) return -ENODEV; - mutex_lock(&ir->buf_lock); + mutex_lock(&rx->buf_lock); - poll_wait(filep, &ir->buf.wait_poll, wait); + poll_wait(filep, &rx->buf.wait_poll, wait); dprintk("poll result = %s\n", - lirc_buffer_empty(&ir->buf) ? "0" : "POLLIN|POLLRDNORM"); + lirc_buffer_empty(&rx->buf) ? "0" : "POLLIN|POLLRDNORM"); - ret = lirc_buffer_empty(&ir->buf) ? 0 : (POLLIN|POLLRDNORM); + ret = lirc_buffer_empty(&rx->buf) ? 0 : (POLLIN|POLLRDNORM); - mutex_unlock(&ir->buf_lock); + mutex_unlock(&rx->buf_lock); return ret; } @@ -994,10 +1012,9 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) int result; unsigned long mode, features = 0; - if (ir->c_rx.addr != 0) + features |= LIRC_CAN_SEND_PULSE; + if (ir->rx != NULL) features |= LIRC_CAN_REC_LIRCCODE; - if (ir->c_tx.addr != 0) - features |= LIRC_CAN_SEND_PULSE; switch (cmd) { case LIRC_GET_LENGTH: @@ -1024,15 +1041,9 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) result = -EINVAL; break; case LIRC_GET_SEND_MODE: - if (!(features&LIRC_CAN_SEND_MASK)) - return -ENOSYS; - result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); break; case LIRC_SET_SEND_MODE: - if (!(features&LIRC_CAN_SEND_MASK)) - return -ENOSYS; - result = get_user(mode, (unsigned long *) arg); if (!result && mode != LIRC_MODE_PULSE) return -EINVAL; @@ -1043,6 +1054,15 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg) return result; } +/* ir_devices_lock must be held */ +static struct IR *find_ir_device_by_minor(unsigned int minor) +{ + if (minor >= MAX_IRCTL_DEVICES) + return NULL; + + return ir_devices[minor]; +} + /* * Open the IR device. Get hold of our IR structure and * stash it in private_data for the file @@ -1051,15 +1071,15 @@ static int open(struct inode *node, struct file *filep) { struct IR *ir; int ret; + unsigned int minor = MINOR(node->i_rdev); /* find our IR struct */ - unsigned minor = MINOR(node->i_rdev); - if (minor >= MAX_IRCTL_DEVICES) { - dprintk("minor %d: open result = -ENODEV\n", - minor); + mutex_lock(&ir_devices_lock); + ir = find_ir_device_by_minor(minor); + mutex_unlock(&ir_devices_lock); + + if (ir == NULL) return -ENODEV; - } - ir = ir_devices[minor]; /* increment in use count */ mutex_lock(&ir->ir_lock); @@ -1106,7 +1126,6 @@ static struct lirc_driver lirc_template = { static int ir_remove(struct i2c_client *client); static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg); #define ID_FLAG_TX 0x01 #define ID_FLAG_HDPVR 0x02 @@ -1126,7 +1145,6 @@ static struct i2c_driver driver = { }, .probe = ir_probe, .remove = ir_remove, - .command = ir_command, .id_table = ir_transceiver_id, }; @@ -1144,214 +1162,253 @@ static const struct file_operations lirc_fops = { .release = close }; -static int ir_remove(struct i2c_client *client) +static void destroy_rx_kthread(struct IR_rx *rx) { - struct IR *ir = i2c_get_clientdata(client); + /* end up polling thread */ + if (rx != NULL && !IS_ERR_OR_NULL(rx->task)) { + kthread_stop(rx->task); + rx->task = NULL; + } +} - mutex_lock(&ir->ir_lock); +/* ir_devices_lock must be held */ +static int add_ir_device(struct IR *ir) +{ + int i; - if (ir->have_rx || ir->have_tx) { - DECLARE_COMPLETION(tn); - DECLARE_COMPLETION(tn2); - - /* end up polling thread */ - if (ir->task && !IS_ERR(ir->task)) { - ir->t_notify = &tn; - ir->t_notify2 = &tn2; - ir->shutdown = 1; - wake_up_process(ir->task); - complete(&tn2); - wait_for_completion(&tn); - ir->t_notify = NULL; - ir->t_notify2 = NULL; + for (i = 0; i < MAX_IRCTL_DEVICES; i++) + if (ir_devices[i] == NULL) { + ir_devices[i] = ir; + break; } - } else { - mutex_unlock(&ir->ir_lock); - zilog_error("%s: detached from something we didn't " - "attach to\n", __func__); - return -ENODEV; + return i == MAX_IRCTL_DEVICES ? -ENOMEM : i; +} + +/* ir_devices_lock must be held */ +static void del_ir_device(struct IR *ir) +{ + int i; + + for (i = 0; i < MAX_IRCTL_DEVICES; i++) + if (ir_devices[i] == ir) { + ir_devices[i] = NULL; + break; + } +} + +static int ir_remove(struct i2c_client *client) +{ + struct IR *ir = i2c_get_clientdata(client); + + mutex_lock(&ir_devices_lock); + + if (ir == NULL) { + /* We destroyed everything when the first client came through */ + mutex_unlock(&ir_devices_lock); + return 0; } - /* unregister lirc driver */ - if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) { - lirc_unregister_driver(ir->l.minor); - ir_devices[ir->l.minor] = NULL; + /* Good-bye LIRC */ + lirc_unregister_driver(ir->l.minor); + + /* Good-bye Rx */ + destroy_rx_kthread(ir->rx); + if (ir->rx != NULL) { + if (ir->rx->buf.fifo_initialized) + lirc_buffer_free(&ir->rx->buf); + i2c_set_clientdata(ir->rx->c, NULL); + kfree(ir->rx); } - /* free memory */ - lirc_buffer_free(&ir->buf); - mutex_unlock(&ir->ir_lock); + /* Good-bye Tx */ + i2c_set_clientdata(ir->tx->c, NULL); + kfree(ir->tx); + + /* Good-bye IR */ + del_ir_device(ir); kfree(ir); + mutex_unlock(&ir_devices_lock); return 0; } -static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) + +/* ir_devices_lock must be held */ +static struct IR *find_ir_device_by_adapter(struct i2c_adapter *adapter) { + int i; struct IR *ir = NULL; + + for (i = 0; i < MAX_IRCTL_DEVICES; i++) + if (ir_devices[i] != NULL && + ir_devices[i]->adapter == adapter) { + ir = ir_devices[i]; + break; + } + + return ir; +} + +static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct IR *ir; struct i2c_adapter *adap = client->adapter; - char buf; int ret; - int have_rx = 0, have_tx = 0; + bool tx_probe = false; - dprintk("%s: adapter name (%s) nr %d, i2c_device_id name (%s), " - "client addr=0x%02x\n", - __func__, adap->name, adap->nr, id->name, client->addr); + dprintk("%s: %s on i2c-%d (%s), client addr=0x%02x\n", + __func__, id->name, adap->nr, adap->name, client->addr); /* - * FIXME - This probe function probes both the Tx and Rx - * addresses of the IR microcontroller. - * - * However, the I2C subsystem is passing along one I2C client at a - * time, based on matches to the ir_transceiver_id[] table above. - * The expectation is that each i2c_client address will be probed - * individually by drivers so the I2C subsystem can mark all client - * addresses as claimed or not. - * - * This probe routine causes only one of the client addresses, TX or RX, - * to be claimed. This will cause a problem if the I2C subsystem is - * subsequently triggered to probe unclaimed clients again. + * The IR receiver is at i2c address 0x71. + * The IR transmitter is at i2c address 0x70. */ - /* - * The external IR receiver is at i2c address 0x71. - * The IR transmitter is at 0x70. - */ - client->addr = 0x70; - if (!disable_tx) { - if (i2c_master_recv(client, &buf, 1) == 1) - have_tx = 1; - dprintk("probe 0x70 @ %s: %s\n", - adap->name, have_tx ? "success" : "failed"); - } + if (id->driver_data & ID_FLAG_TX) + tx_probe = true; + else if (tx_only) /* module option */ + return -ENXIO; - if (!disable_rx) { - client->addr = 0x71; - if (i2c_master_recv(client, &buf, 1) == 1) - have_rx = 1; - dprintk("probe 0x71 @ %s: %s\n", - adap->name, have_rx ? "success" : "failed"); - } + zilog_info("probing IR %s on %s (i2c-%d)\n", + tx_probe ? "Tx" : "Rx", adap->name, adap->nr); - if (!(have_rx || have_tx)) { - zilog_error("%s: no devices found\n", adap->name); - goto out_nodev; - } + mutex_lock(&ir_devices_lock); - printk(KERN_INFO "lirc_zilog: chip found with %s\n", - have_rx && have_tx ? "RX and TX" : - have_rx ? "RX only" : "TX only"); + /* Use a single struct IR instance for both the Rx and Tx functions */ + ir = find_ir_device_by_adapter(adap); + if (ir == NULL) { + ir = kzalloc(sizeof(struct IR), GFP_KERNEL); + if (ir == NULL) { + ret = -ENOMEM; + goto out_no_ir; + } + /* store for use in ir_probe() again, and open() later on */ + ret = add_ir_device(ir); + if (ret) + goto out_free_ir; + + ir->adapter = adap; + mutex_init(&ir->ir_lock); + + /* set lirc_dev stuff */ + memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); + ir->l.minor = minor; /* module option */ + ir->l.code_length = 13; + ir->l.rbuf = NULL; + ir->l.fops = &lirc_fops; + ir->l.data = ir; + ir->l.dev = &adap->dev; + ir->l.sample_rate = 0; + } - ir = kzalloc(sizeof(struct IR), GFP_KERNEL); + if (tx_probe) { + /* Set up a struct IR_tx instance */ + ir->tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL); + if (ir->tx == NULL) { + ret = -ENOMEM; + goto out_free_xx; + } - if (!ir) - goto out_nomem; + ir->tx->c = client; + ir->tx->need_boot = 1; + ir->tx->post_tx_ready_poll = + (id->driver_data & ID_FLAG_HDPVR) ? false : true; + } else { + /* Set up a struct IR_rx instance */ + ir->rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL); + if (ir->rx == NULL) { + ret = -ENOMEM; + goto out_free_xx; + } - ret = lirc_buffer_init(&ir->buf, 2, BUFLEN / 2); - if (ret) - goto out_nomem; + ret = lirc_buffer_init(&ir->rx->buf, 2, BUFLEN / 2); + if (ret) + goto out_free_xx; - mutex_init(&ir->ir_lock); - mutex_init(&ir->buf_lock); - ir->need_boot = 1; - ir->is_hdpvr = (id->driver_data & ID_FLAG_HDPVR) ? true : false; + mutex_init(&ir->rx->buf_lock); + ir->rx->c = client; + ir->rx->hdpvr_data_fmt = + (id->driver_data & ID_FLAG_HDPVR) ? true : false; - memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); - ir->l.minor = -1; + /* set lirc_dev stuff */ + ir->l.rbuf = &ir->rx->buf; + } - /* I2C attach to device */ i2c_set_clientdata(client, ir); - /* initialise RX device */ - if (have_rx) { - DECLARE_COMPLETION(tn); - memcpy(&ir->c_rx, client, sizeof(struct i2c_client)); - - ir->c_rx.addr = 0x71; - strlcpy(ir->c_rx.name, ZILOG_HAUPPAUGE_IR_RX_NAME, - I2C_NAME_SIZE); + /* Proceed only if we have the required Tx and Rx clients ready to go */ + if (ir->tx == NULL || + (ir->rx == NULL && !tx_only)) { + zilog_info("probe of IR %s on %s (i2c-%d) done. Waiting on " + "IR %s.\n", tx_probe ? "Tx" : "Rx", adap->name, + adap->nr, tx_probe ? "Rx" : "Tx"); + goto out_ok; + } + /* initialise RX device */ + if (ir->rx != NULL) { /* try to fire up polling thread */ - ir->t_notify = &tn; - ir->task = kthread_run(lirc_thread, ir, "lirc_zilog"); - if (IS_ERR(ir->task)) { - ret = PTR_ERR(ir->task); - zilog_error("lirc_register_driver: cannot run " - "poll thread %d\n", ret); - goto err; + ir->rx->task = kthread_run(lirc_thread, ir, + "zilog-rx-i2c-%d", adap->nr); + if (IS_ERR(ir->rx->task)) { + ret = PTR_ERR(ir->rx->task); + zilog_error("%s: could not start IR Rx polling thread" + "\n", __func__); + goto out_free_xx; } - wait_for_completion(&tn); - ir->t_notify = NULL; - ir->have_rx = 1; - } - - /* initialise TX device */ - if (have_tx) { - memcpy(&ir->c_tx, client, sizeof(struct i2c_client)); - ir->c_tx.addr = 0x70; - strlcpy(ir->c_tx.name, ZILOG_HAUPPAUGE_IR_TX_NAME, - I2C_NAME_SIZE); - ir->have_tx = 1; } - /* set lirc_dev stuff */ - ir->l.code_length = 13; - ir->l.rbuf = &ir->buf; - ir->l.fops = &lirc_fops; - ir->l.data = ir; - ir->l.minor = minor; - ir->l.dev = &adap->dev; - ir->l.sample_rate = 0; - /* register with lirc */ ir->l.minor = lirc_register_driver(&ir->l); if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { - zilog_error("ir_attach: \"minor\" must be between 0 and %d " - "(%d)!\n", MAX_IRCTL_DEVICES-1, ir->l.minor); + zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n", + __func__, MAX_IRCTL_DEVICES-1, ir->l.minor); ret = -EBADRQC; - goto err; + goto out_free_thread; } - /* store this for getting back in open() later on */ - ir_devices[ir->l.minor] = ir; - /* * if we have the tx device, load the 'firmware'. We do this * after registering with lirc as otherwise hotplug seems to take * 10s to create the lirc device. */ - if (have_tx) { - /* Special TX init */ - ret = tx_init(ir); - if (ret != 0) - goto err; - } + ret = tx_init(ir->tx); + if (ret != 0) + goto out_unregister; + zilog_info("probe of IR %s on %s (i2c-%d) done. IR unit ready.\n", + tx_probe ? "Tx" : "Rx", adap->name, adap->nr); +out_ok: + mutex_unlock(&ir_devices_lock); return 0; -err: - /* undo everything, hopefully... */ - if (ir->c_rx.addr) - ir_remove(&ir->c_rx); - if (ir->c_tx.addr) - ir_remove(&ir->c_tx); - return ret; - -out_nodev: - zilog_error("no device found\n"); - return -ENODEV; - -out_nomem: - zilog_error("memory allocation failure\n"); +out_unregister: + lirc_unregister_driver(ir->l.minor); +out_free_thread: + destroy_rx_kthread(ir->rx); +out_free_xx: + if (ir->rx != NULL) { + if (ir->rx->buf.fifo_initialized) + lirc_buffer_free(&ir->rx->buf); + if (ir->rx->c != NULL) + i2c_set_clientdata(ir->rx->c, NULL); + kfree(ir->rx); + } + if (ir->tx != NULL) { + if (ir->tx->c != NULL) + i2c_set_clientdata(ir->tx->c, NULL); + kfree(ir->tx); + } +out_free_ir: + del_ir_device(ir); kfree(ir); - return -ENOMEM; -} - -static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - /* nothing */ - return 0; +out_no_ir: + zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n", + __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr, + ret); + mutex_unlock(&ir_devices_lock); + return ret; } static int __init zilog_init(void) @@ -1361,6 +1418,7 @@ static int __init zilog_init(void) zilog_notify("Zilog/Hauppauge IR driver initializing\n"); mutex_init(&tx_data_lock); + mutex_init(&ir_devices_lock); request_module("firmware_class"); @@ -1386,7 +1444,8 @@ module_exit(zilog_exit); MODULE_DESCRIPTION("Zilog/Hauppauge infrared transmitter driver (i2c stack)"); MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, " - "Ulrich Mueller, Stefan Jahn, Jerome Brock, Mark Weaver"); + "Ulrich Mueller, Stefan Jahn, Jerome Brock, Mark Weaver, " + "Andy Walls"); MODULE_LICENSE("GPL"); /* for compat with old name, which isn't all that accurate anymore */ MODULE_ALIAS("lirc_pvr150"); @@ -1397,8 +1456,5 @@ MODULE_PARM_DESC(minor, "Preferred minor device number"); module_param(debug, bool, 0644); MODULE_PARM_DESC(debug, "Enable debugging messages"); -module_param(disable_rx, bool, 0644); -MODULE_PARM_DESC(disable_rx, "Disable the IR receiver device"); - -module_param(disable_tx, bool, 0644); -MODULE_PARM_DESC(disable_tx, "Disable the IR transmitter device"); +module_param(tx_only, bool, 0644); +MODULE_PARM_DESC(tx_only, "Only handle the IR transmit function"); diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c index 8fe017c..eb9b9f1 100644 --- a/drivers/staging/tm6000/tm6000-video.c +++ b/drivers/staging/tm6000/tm6000-video.c @@ -1450,29 +1450,55 @@ static struct video_device tm6000_template = { * ------------------------------------------------------------------ */ -int tm6000_v4l2_register(struct tm6000_core *dev) +static struct video_device *vdev_init(struct tm6000_core *dev, + const struct video_device + *template, const char *type_name) { - int ret = -1; struct video_device *vfd; vfd = video_device_alloc(); - if(!vfd) { + if (NULL == vfd) + return NULL; + + *vfd = *template; + vfd->v4l2_dev = &dev->v4l2_dev; + vfd->release = video_device_release; + vfd->debug = tm6000_debug; + vfd->lock = &dev->lock; + + snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); + + video_set_drvdata(vfd, dev); + return vfd; +} + +int tm6000_v4l2_register(struct tm6000_core *dev) +{ + int ret = -1; + + dev->vfd = vdev_init(dev, &tm6000_template, "video"); + + if (!dev->vfd) { + printk(KERN_INFO "%s: can't register video device\n", + dev->name); return -ENOMEM; } - dev->vfd = vfd; /* init video dma queues */ INIT_LIST_HEAD(&dev->vidq.active); INIT_LIST_HEAD(&dev->vidq.queued); - memcpy(dev->vfd, &tm6000_template, sizeof(*(dev->vfd))); - dev->vfd->debug = tm6000_debug; - dev->vfd->lock = &dev->lock; + ret = video_register_device(dev->vfd, VFL_TYPE_GRABBER, video_nr); - vfd->v4l2_dev = &dev->v4l2_dev; - video_set_drvdata(vfd, dev); + if (ret < 0) { + printk(KERN_INFO "%s: can't register video device\n", + dev->name); + return ret; + } + + printk(KERN_INFO "%s: registered device %s\n", + dev->name, video_device_node_name(dev->vfd)); - ret = video_register_device(dev->vfd, VFL_TYPE_GRABBER, video_nr); printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); return ret; } diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index c43ef48..3962772 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -9,3 +9,5 @@ obj-$(CONFIG_N_GSM) += n_gsm.o obj-$(CONFIG_R3964) += n_r3964.o obj-y += vt/ +obj-$(CONFIG_HVC_DRIVER) += hvc/ +obj-y += serial/ diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile new file mode 100644 index 0000000..e6bed5f --- /dev/null +++ b/drivers/tty/hvc/Makefile @@ -0,0 +1,13 @@ +obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o +obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o +obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o +obj-$(CONFIG_HVC_TILE) += hvc_tile.o +obj-$(CONFIG_HVC_DCC) += hvc_dcc.o +obj-$(CONFIG_HVC_BEAT) += hvc_beat.o +obj-$(CONFIG_HVC_DRIVER) += hvc_console.o +obj-$(CONFIG_HVC_IRQ) += hvc_irq.o +obj-$(CONFIG_HVC_XEN) += hvc_xen.o +obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o +obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o +obj-$(CONFIG_HVCS) += hvcs.o +obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o diff --git a/drivers/char/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c index 5fe4631..5fe4631 100644 --- a/drivers/char/hvc_beat.c +++ b/drivers/tty/hvc/hvc_beat.c diff --git a/drivers/char/hvc_console.c b/drivers/tty/hvc/hvc_console.c index e9cba13..e9cba13 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c diff --git a/drivers/char/hvc_console.h b/drivers/tty/hvc/hvc_console.h index 54381eba..54381eba 100644 --- a/drivers/char/hvc_console.h +++ b/drivers/tty/hvc/hvc_console.h diff --git a/drivers/char/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index 6470f63..6470f63 100644 --- a/drivers/char/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c diff --git a/drivers/char/hvc_irq.c b/drivers/tty/hvc/hvc_irq.c index 2623e17..2623e17 100644 --- a/drivers/char/hvc_irq.c +++ b/drivers/tty/hvc/hvc_irq.c diff --git a/drivers/char/hvc_iseries.c b/drivers/tty/hvc/hvc_iseries.c index 21c5495..21c5495 100644 --- a/drivers/char/hvc_iseries.c +++ b/drivers/tty/hvc/hvc_iseries.c diff --git a/drivers/char/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c index c3425bb..c3425bb 100644 --- a/drivers/char/hvc_iucv.c +++ b/drivers/tty/hvc/hvc_iucv.c diff --git a/drivers/char/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c index 61c4a61..61c4a61 100644 --- a/drivers/char/hvc_rtas.c +++ b/drivers/tty/hvc/hvc_rtas.c diff --git a/drivers/char/hvc_tile.c b/drivers/tty/hvc/hvc_tile.c index 7a84a05..7a84a05 100644 --- a/drivers/char/hvc_tile.c +++ b/drivers/tty/hvc/hvc_tile.c diff --git a/drivers/char/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c index b0957e6..b0957e6 100644 --- a/drivers/char/hvc_udbg.c +++ b/drivers/tty/hvc/hvc_udbg.c diff --git a/drivers/char/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 5e2f52b..5e2f52b 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c diff --git a/drivers/char/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 3740e32..3740e32 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c diff --git a/drivers/char/hvcs.c b/drivers/tty/hvc/hvcs.c index bedc6c1..bedc6c1 100644 --- a/drivers/char/hvcs.c +++ b/drivers/tty/hvc/hvcs.c diff --git a/drivers/char/hvsi.c b/drivers/tty/hvc/hvsi.c index 67a75a5..67a75a5 100644 --- a/drivers/char/hvsi.c +++ b/drivers/tty/hvc/hvsi.c diff --git a/drivers/char/virtio_console.c b/drivers/tty/hvc/virtio_console.c index 896a2ce..896a2ce 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/tty/hvc/virtio_console.c diff --git a/drivers/serial/21285.c b/drivers/tty/serial/21285.c index d89aa38..d89aa38 100644 --- a/drivers/serial/21285.c +++ b/drivers/tty/serial/21285.c diff --git a/drivers/serial/68328serial.c b/drivers/tty/serial/68328serial.c index be0ebce..be0ebce 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c diff --git a/drivers/serial/68328serial.h b/drivers/tty/serial/68328serial.h index 664ceb0..664ceb0 100644 --- a/drivers/serial/68328serial.h +++ b/drivers/tty/serial/68328serial.h diff --git a/drivers/serial/68360serial.c b/drivers/tty/serial/68360serial.c index 88b1335..88b1335 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/tty/serial/68360serial.c diff --git a/drivers/serial/8250.c b/drivers/tty/serial/8250.c index b25e6e4..b25e6e4 100644 --- a/drivers/serial/8250.c +++ b/drivers/tty/serial/8250.c diff --git a/drivers/serial/8250.h b/drivers/tty/serial/8250.h index 6e19ea3..6e19ea3 100644 --- a/drivers/serial/8250.h +++ b/drivers/tty/serial/8250.h diff --git a/drivers/serial/8250_accent.c b/drivers/tty/serial/8250_accent.c index 9c10262..9c10262 100644 --- a/drivers/serial/8250_accent.c +++ b/drivers/tty/serial/8250_accent.c diff --git a/drivers/serial/8250_acorn.c b/drivers/tty/serial/8250_acorn.c index b0ce8c5..b0ce8c5 100644 --- a/drivers/serial/8250_acorn.c +++ b/drivers/tty/serial/8250_acorn.c diff --git a/drivers/serial/8250_boca.c b/drivers/tty/serial/8250_boca.c index 3bfe0f7..3bfe0f7 100644 --- a/drivers/serial/8250_boca.c +++ b/drivers/tty/serial/8250_boca.c diff --git a/drivers/serial/8250_early.c b/drivers/tty/serial/8250_early.c index eaafb98..eaafb98 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/tty/serial/8250_early.c diff --git a/drivers/serial/8250_exar_st16c554.c b/drivers/tty/serial/8250_exar_st16c554.c index 567143a..567143a 100644 --- a/drivers/serial/8250_exar_st16c554.c +++ b/drivers/tty/serial/8250_exar_st16c554.c diff --git a/drivers/serial/8250_fourport.c b/drivers/tty/serial/8250_fourport.c index 6375d68..6375d68 100644 --- a/drivers/serial/8250_fourport.c +++ b/drivers/tty/serial/8250_fourport.c diff --git a/drivers/serial/8250_gsc.c b/drivers/tty/serial/8250_gsc.c index d8c0ffb..d8c0ffb 100644 --- a/drivers/serial/8250_gsc.c +++ b/drivers/tty/serial/8250_gsc.c diff --git a/drivers/serial/8250_hp300.c b/drivers/tty/serial/8250_hp300.c index c13438c..c13438c 100644 --- a/drivers/serial/8250_hp300.c +++ b/drivers/tty/serial/8250_hp300.c diff --git a/drivers/serial/8250_hub6.c b/drivers/tty/serial/8250_hub6.c index 7609150..7609150 100644 --- a/drivers/serial/8250_hub6.c +++ b/drivers/tty/serial/8250_hub6.c diff --git a/drivers/serial/8250_mca.c b/drivers/tty/serial/8250_mca.c index d10be94..d10be94 100644 --- a/drivers/serial/8250_mca.c +++ b/drivers/tty/serial/8250_mca.c diff --git a/drivers/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 8b8930f..8b8930f 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c diff --git a/drivers/serial/8250_pnp.c b/drivers/tty/serial/8250_pnp.c index 4822cb5..4822cb5 100644 --- a/drivers/serial/8250_pnp.c +++ b/drivers/tty/serial/8250_pnp.c diff --git a/drivers/serial/Kconfig b/drivers/tty/serial/Kconfig index c1df767..b1682d7 100644 --- a/drivers/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -81,7 +81,7 @@ config SERIAL_8250_GSC default SERIAL_8250 config SERIAL_8250_PCI - tristate "8250/16550 PCI device support" if EMBEDDED + tristate "8250/16550 PCI device support" if EXPERT depends on SERIAL_8250 && PCI default SERIAL_8250 help @@ -90,7 +90,7 @@ config SERIAL_8250_PCI Saves about 9K. config SERIAL_8250_PNP - tristate "8250/16550 PNP device support" if EMBEDDED + tristate "8250/16550 PNP device support" if EXPERT depends on SERIAL_8250 && PNP default SERIAL_8250 help diff --git a/drivers/serial/Makefile b/drivers/tty/serial/Makefile index 8ea92e9..8ea92e9 100644 --- a/drivers/serial/Makefile +++ b/drivers/tty/serial/Makefile diff --git a/drivers/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c index f9b49b5..f9b49b5 100644 --- a/drivers/serial/altera_jtaguart.c +++ b/drivers/tty/serial/altera_jtaguart.c diff --git a/drivers/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 7212162..7212162 100644 --- a/drivers/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c diff --git a/drivers/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 2904aa0..2904aa0 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c diff --git a/drivers/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index e76d7d0..e76d7d0 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c diff --git a/drivers/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 095a5d5..095a5d5 100644 --- a/drivers/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c diff --git a/drivers/serial/apbuart.h b/drivers/tty/serial/apbuart.h index 5faf87c..5faf87c 100644 --- a/drivers/serial/apbuart.h +++ b/drivers/tty/serial/apbuart.h diff --git a/drivers/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 2a1d52f..2a1d52f 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c diff --git a/drivers/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index a1a0e55..a1a0e55 100644 --- a/drivers/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c diff --git a/drivers/serial/bfin_5xx.c b/drivers/tty/serial/bfin_5xx.c index e381b89..e381b89 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/tty/serial/bfin_5xx.c diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/tty/serial/bfin_sport_uart.c index e95c524..e95c524 100644 --- a/drivers/serial/bfin_sport_uart.c +++ b/drivers/tty/serial/bfin_sport_uart.c diff --git a/drivers/serial/bfin_sport_uart.h b/drivers/tty/serial/bfin_sport_uart.h index 6d06ce1..6d06ce1 100644 --- a/drivers/serial/bfin_sport_uart.h +++ b/drivers/tty/serial/bfin_sport_uart.h diff --git a/drivers/serial/clps711x.c b/drivers/tty/serial/clps711x.c index b6acd19..b6acd19 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c diff --git a/drivers/serial/cpm_uart/Makefile b/drivers/tty/serial/cpm_uart/Makefile index e072724..e072724 100644 --- a/drivers/serial/cpm_uart/Makefile +++ b/drivers/tty/serial/cpm_uart/Makefile diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/tty/serial/cpm_uart/cpm_uart.h index b754dcf..b754dcf 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart.h diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/tty/serial/cpm_uart/cpm_uart_core.c index 8692ff9..8692ff9 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_core.c diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c index 3fc1d66..3fc1d66 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h index 10eecd6..10eecd6 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c index 814ac00..814ac00 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h index 7194c63..7194c63 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h diff --git a/drivers/serial/crisv10.c b/drivers/tty/serial/crisv10.c index bcc31f2..bcc31f2 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c diff --git a/drivers/serial/crisv10.h b/drivers/tty/serial/crisv10.h index ea0beb46..ea0beb46 100644 --- a/drivers/serial/crisv10.h +++ b/drivers/tty/serial/crisv10.h diff --git a/drivers/serial/dz.c b/drivers/tty/serial/dz.c index 57421d7..57421d7 100644 --- a/drivers/serial/dz.c +++ b/drivers/tty/serial/dz.c diff --git a/drivers/serial/dz.h b/drivers/tty/serial/dz.h index faf169e..faf169e 100644 --- a/drivers/serial/dz.h +++ b/drivers/tty/serial/dz.h diff --git a/drivers/serial/icom.c b/drivers/tty/serial/icom.c index 53a4682..53a4682 100644 --- a/drivers/serial/icom.c +++ b/drivers/tty/serial/icom.c diff --git a/drivers/serial/icom.h b/drivers/tty/serial/icom.h index c8029e0..c8029e0 100644 --- a/drivers/serial/icom.h +++ b/drivers/tty/serial/icom.h diff --git a/drivers/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index ab93763..ab93763 100644 --- a/drivers/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c diff --git a/drivers/serial/ifx6x60.h b/drivers/tty/serial/ifx6x60.h index deb7b8d..deb7b8d 100644 --- a/drivers/serial/ifx6x60.h +++ b/drivers/tty/serial/ifx6x60.h diff --git a/drivers/serial/imx.c b/drivers/tty/serial/imx.c index dfcf4b1..dfcf4b1 100644 --- a/drivers/serial/imx.c +++ b/drivers/tty/serial/imx.c diff --git a/drivers/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index ee43efc..ee43efc 100644 --- a/drivers/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c diff --git a/drivers/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index fcfe826..fcfe826 100644 --- a/drivers/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c diff --git a/drivers/serial/ip22zilog.c b/drivers/tty/serial/ip22zilog.c index ebff4a1..ebff4a1 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/tty/serial/ip22zilog.c diff --git a/drivers/serial/ip22zilog.h b/drivers/tty/serial/ip22zilog.h index a59a9a8..a59a9a8 100644 --- a/drivers/serial/ip22zilog.h +++ b/drivers/tty/serial/ip22zilog.h diff --git a/drivers/serial/jsm/Makefile b/drivers/tty/serial/jsm/Makefile index e46b6e0..e46b6e0 100644 --- a/drivers/serial/jsm/Makefile +++ b/drivers/tty/serial/jsm/Makefile diff --git a/drivers/serial/jsm/jsm.h b/drivers/tty/serial/jsm/jsm.h index 38a509c..38a509c 100644 --- a/drivers/serial/jsm/jsm.h +++ b/drivers/tty/serial/jsm/jsm.h diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 18f5484..18f5484 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/tty/serial/jsm/jsm_neo.c index 7960d96..7960d96 100644 --- a/drivers/serial/jsm/jsm_neo.c +++ b/drivers/tty/serial/jsm/jsm_neo.c diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 7a4a914..7a4a914 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c diff --git a/drivers/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index 25a8bc5..25a8bc5 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c diff --git a/drivers/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index bea5c21..bea5c21 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c diff --git a/drivers/serial/m32r_sio.h b/drivers/tty/serial/m32r_sio.h index e9b7e11..e9b7e11 100644 --- a/drivers/serial/m32r_sio.h +++ b/drivers/tty/serial/m32r_sio.h diff --git a/drivers/serial/m32r_sio_reg.h b/drivers/tty/serial/m32r_sio_reg.h index 4671473..4671473 100644 --- a/drivers/serial/m32r_sio_reg.h +++ b/drivers/tty/serial/m32r_sio_reg.h diff --git a/drivers/serial/max3100.c b/drivers/tty/serial/max3100.c index beb1afa..beb1afa 100644 --- a/drivers/serial/max3100.c +++ b/drivers/tty/serial/max3100.c diff --git a/drivers/serial/max3107-aava.c b/drivers/tty/serial/max3107-aava.c index a1fe304..a1fe304 100644 --- a/drivers/serial/max3107-aava.c +++ b/drivers/tty/serial/max3107-aava.c diff --git a/drivers/serial/max3107.c b/drivers/tty/serial/max3107.c index 910870e..910870e 100644 --- a/drivers/serial/max3107.c +++ b/drivers/tty/serial/max3107.c diff --git a/drivers/serial/max3107.h b/drivers/tty/serial/max3107.h index 7ab63239..7ab63239 100644 --- a/drivers/serial/max3107.h +++ b/drivers/tty/serial/max3107.h diff --git a/drivers/serial/mcf.c b/drivers/tty/serial/mcf.c index 3394b7c..3394b7c 100644 --- a/drivers/serial/mcf.c +++ b/drivers/tty/serial/mcf.c diff --git a/drivers/serial/mfd.c b/drivers/tty/serial/mfd.c index d40010a..d40010a 100644 --- a/drivers/serial/mfd.c +++ b/drivers/tty/serial/mfd.c diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 126ec7f..126ec7f 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c diff --git a/drivers/serial/mpsc.c b/drivers/tty/serial/mpsc.c index 6a9c660..6a9c660 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/tty/serial/mpsc.c diff --git a/drivers/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index b62857b..b62857b 100644 --- a/drivers/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c diff --git a/drivers/serial/mrst_max3110.h b/drivers/tty/serial/mrst_max3110.h index d1ef43a..d1ef43a 100644 --- a/drivers/serial/mrst_max3110.h +++ b/drivers/tty/serial/mrst_max3110.h diff --git a/drivers/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 8e43a7b..8e43a7b 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c diff --git a/drivers/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h index f6ca9ca..f6ca9ca 100644 --- a/drivers/serial/msm_serial.h +++ b/drivers/tty/serial/msm_serial.h diff --git a/drivers/serial/mux.c b/drivers/tty/serial/mux.c index 9711e06..9711e06 100644 --- a/drivers/serial/mux.c +++ b/drivers/tty/serial/mux.c diff --git a/drivers/serial/netx-serial.c b/drivers/tty/serial/netx-serial.c index 7735c9f..7735c9f 100644 --- a/drivers/serial/netx-serial.c +++ b/drivers/tty/serial/netx-serial.c diff --git a/drivers/serial/nwpserial.c b/drivers/tty/serial/nwpserial.c index de17367..de17367 100644 --- a/drivers/serial/nwpserial.c +++ b/drivers/tty/serial/nwpserial.c diff --git a/drivers/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 5c7abe4..5c7abe4 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c diff --git a/drivers/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 7f2f010..7f2f010 100644 --- a/drivers/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c diff --git a/drivers/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 70a6145..70a6145 100644 --- a/drivers/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c diff --git a/drivers/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 5b9cde7..5b9cde7 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c diff --git a/drivers/serial/pmac_zilog.h b/drivers/tty/serial/pmac_zilog.h index cbc34fb..cbc34fb 100644 --- a/drivers/serial/pmac_zilog.h +++ b/drivers/tty/serial/pmac_zilog.h diff --git a/drivers/serial/pnx8xxx_uart.c b/drivers/tty/serial/pnx8xxx_uart.c index 0aa75a9..0aa75a9 100644 --- a/drivers/serial/pnx8xxx_uart.c +++ b/drivers/tty/serial/pnx8xxx_uart.c diff --git a/drivers/serial/pxa.c b/drivers/tty/serial/pxa.c index 1102a39..1102a39 100644 --- a/drivers/serial/pxa.c +++ b/drivers/tty/serial/pxa.c diff --git a/drivers/serial/s3c2400.c b/drivers/tty/serial/s3c2400.c index fed1a9a..fed1a9a 100644 --- a/drivers/serial/s3c2400.c +++ b/drivers/tty/serial/s3c2400.c diff --git a/drivers/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c index 73f089d..73f089d 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/tty/serial/s3c2410.c diff --git a/drivers/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c index 1700b1a..1700b1a 100644 --- a/drivers/serial/s3c2412.c +++ b/drivers/tty/serial/s3c2412.c diff --git a/drivers/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c index 094cc39..094cc39 100644 --- a/drivers/serial/s3c2440.c +++ b/drivers/tty/serial/s3c2440.c diff --git a/drivers/serial/s3c24a0.c b/drivers/tty/serial/s3c24a0.c index fad6083..fad6083 100644 --- a/drivers/serial/s3c24a0.c +++ b/drivers/tty/serial/s3c24a0.c diff --git a/drivers/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c index 4be92ab..4be92ab 100644 --- a/drivers/serial/s3c6400.c +++ b/drivers/tty/serial/s3c6400.c diff --git a/drivers/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c index 6ebccd7..6ebccd7 100644 --- a/drivers/serial/s5pv210.c +++ b/drivers/tty/serial/s5pv210.c diff --git a/drivers/serial/sa1100.c b/drivers/tty/serial/sa1100.c index 2199d81..2199d81 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/tty/serial/sa1100.c diff --git a/drivers/serial/samsung.c b/drivers/tty/serial/samsung.c index 2335eda..2335eda 100644 --- a/drivers/serial/samsung.c +++ b/drivers/tty/serial/samsung.c diff --git a/drivers/serial/samsung.h b/drivers/tty/serial/samsung.h index 0ac06a0..0ac06a0 100644 --- a/drivers/serial/samsung.h +++ b/drivers/tty/serial/samsung.h diff --git a/drivers/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index a2f2b32..a2f2b32 100644 --- a/drivers/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c diff --git a/drivers/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c index 75038ad..75038ad 100644 --- a/drivers/serial/sc26xx.c +++ b/drivers/tty/serial/sc26xx.c diff --git a/drivers/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 460a72d..460a72d 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c diff --git a/drivers/serial/serial_cs.c b/drivers/tty/serial/serial_cs.c index 93760b2..93760b2 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/tty/serial/serial_cs.c diff --git a/drivers/serial/serial_ks8695.c b/drivers/tty/serial/serial_ks8695.c index b196202..b196202 100644 --- a/drivers/serial/serial_ks8695.c +++ b/drivers/tty/serial/serial_ks8695.c diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/tty/serial/serial_lh7a40x.c index ea74470..ea74470 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/tty/serial/serial_lh7a40x.c diff --git a/drivers/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index c50e9fb..c50e9fb 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c diff --git a/drivers/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 92c91c8..92c91c8 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c diff --git a/drivers/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index b223d6c..b223d6c 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h diff --git a/drivers/serial/sn_console.c b/drivers/tty/serial/sn_console.c index cff9a30..cff9a30 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/tty/serial/sn_console.c diff --git a/drivers/serial/suncore.c b/drivers/tty/serial/suncore.c index 6381a02..6381a02 100644 --- a/drivers/serial/suncore.c +++ b/drivers/tty/serial/suncore.c diff --git a/drivers/serial/suncore.h b/drivers/tty/serial/suncore.h index db20579..db20579 100644 --- a/drivers/serial/suncore.h +++ b/drivers/tty/serial/suncore.h diff --git a/drivers/serial/sunhv.c b/drivers/tty/serial/sunhv.c index c901486..c901486 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c diff --git a/drivers/serial/sunsab.c b/drivers/tty/serial/sunsab.c index 5b246b1..5b246b1 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c diff --git a/drivers/serial/sunsab.h b/drivers/tty/serial/sunsab.h index b78e1f7..b78e1f7 100644 --- a/drivers/serial/sunsab.h +++ b/drivers/tty/serial/sunsab.h diff --git a/drivers/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 551ebfe..551ebfe 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c diff --git a/drivers/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index c1967ac..c1967ac 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c diff --git a/drivers/serial/sunzilog.h b/drivers/tty/serial/sunzilog.h index 5dec7b4..5dec7b4 100644 --- a/drivers/serial/sunzilog.h +++ b/drivers/tty/serial/sunzilog.h diff --git a/drivers/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 1f36b7e..1f36b7e 100644 --- a/drivers/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c diff --git a/drivers/serial/timbuart.h b/drivers/tty/serial/timbuart.h index 7e56676..7e56676 100644 --- a/drivers/serial/timbuart.h +++ b/drivers/tty/serial/timbuart.h diff --git a/drivers/serial/uartlite.c b/drivers/tty/serial/uartlite.c index d2fce86..d2fce86 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c diff --git a/drivers/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 3f4848e..3f4848e 100644 --- a/drivers/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c diff --git a/drivers/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 3beb6ab..3beb6ab 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c diff --git a/drivers/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index 322bf56..322bf56 100644 --- a/drivers/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c diff --git a/drivers/serial/zs.c b/drivers/tty/serial/zs.c index 1a7fd3e..1a7fd3e 100644 --- a/drivers/serial/zs.c +++ b/drivers/tty/serial/zs.c diff --git a/drivers/serial/zs.h b/drivers/tty/serial/zs.h index aa921b5..aa921b5 100644 --- a/drivers/serial/zs.h +++ b/drivers/tty/serial/zs.h diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index bcc2477..18d02e3 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -123,9 +123,9 @@ config USB_OTG config USB_OTG_WHITELIST bool "Rely on OTG Targeted Peripherals List" - depends on USB_OTG || EMBEDDED + depends on USB_OTG || EXPERT default y if USB_OTG - default n if EMBEDDED + default n if EXPERT help If you say Y here, the "otg_whitelist.h" file will be used as a product whitelist, so USB peripherals not listed there will be @@ -141,7 +141,7 @@ config USB_OTG_WHITELIST config USB_OTG_BLACKLIST_HUB bool "Disable external hubs" - depends on USB_OTG || EMBEDDED + depends on USB_OTG || EXPERT help If you say Y here, then Linux will refuse to enumerate external hubs. OTG hosts are allowed to reduce hardware diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d916ac0..6bafb51b 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1227,7 +1227,7 @@ config FB_CARILLO_RANCH config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" - depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL && EMBEDDED + depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL && EXPERT select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index c789c46..b224396 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -21,7 +21,7 @@ #define MAX_BRIGHTNESS (0xFF) #define MIN_BRIGHTNESS (0) -#define CURRENT_MASK (0x1F << 1) +#define CURRENT_BITMASK (0x1F << 1) struct pm860x_backlight_data { struct pm860x_chip *chip; @@ -85,7 +85,7 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness) if ((data->current_brightness == 0) && brightness) { if (data->iset) { ret = pm860x_set_bits(data->i2c, wled_idc(data->port), - CURRENT_MASK, data->iset); + CURRENT_BITMASK, data->iset); if (ret < 0) goto out; } diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 5a35f22..2209e35 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -5,7 +5,7 @@ menu "Console display driver support" config VGA_CONSOLE - bool "VGA text console" if EMBEDDED || !X86 + bool "VGA text console" if EXPERT || !X86 depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !SUPERH && !BLACKFIN && !AVR32 && !MN10300 && (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) default y help diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index ef8d9d5..4fb5b2b 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); diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index 1c12360..bbd000f 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c @@ -122,6 +122,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) @@ -144,7 +145,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; @@ -160,6 +161,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); @@ -407,6 +410,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); } @@ -455,7 +459,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; } @@ -488,21 +492,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 */ @@ -510,7 +499,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) @@ -555,6 +545,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, @@ -573,6 +564,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; |