diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2011-04-07 11:15:50 -0700 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-04-07 11:15:50 -0700 |
commit | 454abcc57f1d48a976291bc4af73b5f087e21d70 (patch) | |
tree | 5bba999ea3f31527da02b60604531cc5fb52ea57 | |
parent | 88aab9341a315d81118be6b41c45e4fe32b94bc1 (diff) | |
parent | 6221f222c0ebf1acdf7abcf927178f40e1a65e2a (diff) |
Merge commit 'v2.6.39-rc2' into spi/merge
444 files changed, 3815 insertions, 2296 deletions
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index f607367e642f..c17cd4bb2290 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -206,8 +206,8 @@ laptops/ - directory with laptop related info and laptop driver documentation. ldm.txt - a brief description of LDM (Windows Dynamic Disks). -leds-class.txt - - documents LED handling under Linux. +leds/ + - directory with info about LED handling under Linux. local_ops.txt - semantics and behavior of local atomic operations. lockdep-design.txt diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone index b4c4f158ab9c..3ca3971109bf 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone @@ -40,7 +40,7 @@ What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid- Date: March 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the - press of a button. A profile holds informations like button + press of a button. A profile holds information like button mappings, sensitivity, the colors of the 5 leds and light effects. When read, these files return the respective profile. The diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus index 00efced73969..326e05452da7 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus @@ -33,7 +33,7 @@ Date: August 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_buttons holds informations about button layout. + profile_buttons holds information about button layout. When written, this file lets one write the respective profile buttons back to the mouse. The data has to be 77 bytes long. The mouse will reject invalid data. @@ -47,7 +47,7 @@ Date: August 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_buttons holds informations about button layout. + profile_buttons holds information about button layout. When read, these files return the respective profile buttons. The returned data is 77 bytes in size. This file is readonly. @@ -58,7 +58,7 @@ Date: October 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_settings holds informations like resolution, sensitivity + profile_settings holds information like resolution, sensitivity and light effects. When written, this file lets one write the respective profile settings back to the mouse. The data has to be 43 bytes long. @@ -73,7 +73,7 @@ Date: August 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_settings holds informations like resolution, sensitivity + profile_settings holds information like resolution, sensitivity and light effects. When read, these files return the respective profile settings. The returned data is 43 bytes in size. diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus index fdfa16f8189b..20f937c9d84f 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus @@ -52,7 +52,7 @@ Date: January 2011 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_buttons holds informations about button layout. + profile_buttons holds information about button layout. When written, this file lets one write the respective profile buttons back to the mouse. The data has to be 23 bytes long. The mouse will reject invalid data. @@ -66,7 +66,7 @@ Date: January 2011 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_buttons holds informations about button layout. + profile_buttons holds information about button layout. When read, these files return the respective profile buttons. The returned data is 23 bytes in size. This file is readonly. @@ -77,7 +77,7 @@ Date: January 2011 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_settings holds informations like resolution, sensitivity + profile_settings holds information like resolution, sensitivity and light effects. When written, this file lets one write the respective profile settings back to the mouse. The data has to be 16 bytes long. @@ -92,7 +92,7 @@ Date: January 2011 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_settings holds informations like resolution, sensitivity + profile_settings holds information like resolution, sensitivity and light effects. When read, these files return the respective profile settings. The returned data is 16 bytes in size. diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra index 5fab71af3c46..3f8de50e4ff1 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra @@ -39,7 +39,7 @@ Date: August 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_settings holds informations like resolution, sensitivity + profile_settings holds information like resolution, sensitivity and light effects. When written, this file lets one write the respective profile settings back to the mouse. The data has to be 13 bytes long. @@ -54,7 +54,7 @@ Date: August 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_settings holds informations like resolution, sensitivity + profile_settings holds information like resolution, sensitivity and light effects. When read, these files return the respective profile settings. The returned data is 13 bytes in size. @@ -66,7 +66,7 @@ Date: August 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_buttons holds informations about button layout. + profile_buttons holds information about button layout. When written, this file lets one write the respective profile buttons back to the mouse. The data has to be 19 bytes long. The mouse will reject invalid data. @@ -80,7 +80,7 @@ Date: August 2010 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> Description: The mouse can store 5 profiles which can be switched by the press of a button. A profile is split in settings and buttons. - profile_buttons holds informations about button layout. + profile_buttons holds information about button layout. When read, these files return the respective profile buttons. The returned data is 19 bytes in size. This file is readonly. diff --git a/Documentation/ABI/testing/sysfs-platform-asus-laptop b/Documentation/ABI/testing/sysfs-platform-asus-laptop index 41ff8ae4dee0..cd9d667c3da2 100644 --- a/Documentation/ABI/testing/sysfs-platform-asus-laptop +++ b/Documentation/ABI/testing/sysfs-platform-asus-laptop @@ -27,7 +27,7 @@ KernelVersion: 2.6.20 Contact: "Corentin Chary" <corentincj@iksaif.net> Description: Some models like the W1N have a LED display that can be - used to display several informations. + used to display several items of information. To control the LED display, use the following : echo 0x0T000DDD > /sys/devices/platform/asus_laptop/ where T control the 3 letters display, and DDD the 3 digits display. diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index cbdfb7d9455b..aedf1bd02fdd 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -110,22 +110,22 @@ university server with various users - students, professors, system tasks etc. The resource planning for this server could be along the following lines: - CPU : Top cpuset + CPU : "Top cpuset" / \ CPUSet1 CPUSet2 - | | - (Profs) (Students) + | | + (Professors) (Students) In addition (system tasks) are attached to topcpuset (so that they can run anywhere) with a limit of 20% - Memory : Professors (50%), students (30%), system (20%) + Memory : Professors (50%), Students (30%), system (20%) - Disk : Prof (50%), students (30%), system (20%) + Disk : Professors (50%), Students (30%), system (20%) Network : WWW browsing (20%), Network File System (60%), others (20%) / \ - Prof (15%) students (5%) + Professors (15%) students (5%) Browsers like Firefox/Lynx go into the WWW network class, while (k)nfsd go into NFS network class. diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index 55fd2623445b..50619a0720a8 100644 --- a/Documentation/devicetree/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt @@ -138,7 +138,7 @@ and properties to be present. This will be described in detail in section III, but, for example, the kernel does not require you to create a node for every PCI device in the system. It is a requirement to have a node for PCI host bridges in order to provide interrupt -routing informations and memory/IO ranges, among others. It is also +routing information and memory/IO ranges, among others. It is also recommended to define nodes for on chip devices and other buses that don't specifically fit in an existing OF specification. This creates a great flexibility in the way the kernel can then probe those and match @@ -385,7 +385,7 @@ struct boot_param_header { among others, by kexec. If you are on an SMP system, this value should match the content of the "reg" property of the CPU node in the device-tree corresponding to the CPU calling the kernel entry - point (see further chapters for more informations on the required + point (see further chapters for more information on the required device-tree contents) - size_dt_strings @@ -553,7 +553,7 @@ looks like in practice. This tree is almost a minimal tree. It pretty much contains the minimal set of required nodes and properties to boot a linux kernel; -that is, some basic model informations at the root, the CPUs, and the +that is, some basic model information at the root, the CPUs, and the physical memory layout. It also includes misc information passed through /chosen, like in this example, the platform type (mandatory) and the kernel command line arguments (optional). diff --git a/Documentation/dvb/udev.txt b/Documentation/dvb/udev.txt index 68ee224b6aae..412305b7c557 100644 --- a/Documentation/dvb/udev.txt +++ b/Documentation/dvb/udev.txt @@ -1,7 +1,7 @@ The DVB subsystem currently registers to the sysfs subsystem using the "class_simple" interface. -This means that only the basic informations like module loading parameters +This means that only the basic information like module loading parameters are presented through sysfs. Other things that might be interesting are currently *not* available. diff --git a/Documentation/edac.txt b/Documentation/edac.txt index 9ee774de57cd..ccc07c28967e 100644 --- a/Documentation/edac.txt +++ b/Documentation/edac.txt @@ -311,7 +311,7 @@ Total Correctable Errors count attribute file: 'ce_noinfo_count' This attribute file displays the number of CEs that - have occurred wherewith no informations as to which DIMM slot + have occurred wherewith no information as to which DIMM slot is having errors. Memory is handicapped, but operational, yet no information is available to indicate which slot the failing memory is in. This count field should be also diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index c357a31411cd..d2b515000e40 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1832,15 +1832,17 @@ bytes respectively. Such letter suffixes can also be entirely omitted. perfmon on Intel CPUs instead of the CPU specific event set. - oops=panic Always panic on oopses. Default is to just kill the process, - but there is a small probability of deadlocking the machine. + oops=panic Always panic on oopses. Default is to just kill the + process, but there is a small probability of + deadlocking the machine. This will also cause panics on machine check exceptions. Useful together with panic=30 to trigger a reboot. OSS [HW,OSS] See Documentation/sound/oss/oss-parameters.txt - panic= [KNL] Kernel behaviour on panic + panic= [KNL] Kernel behaviour on panic: delay <timeout> + seconds before rebooting Format: <timeout> parkbd.port= [HW] Parallel port number the keyboard adapter is @@ -2343,6 +2345,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. softlockup_panic= [KNL] Should the soft-lockup detector generate panics. + Format: <integer> sonypi.*= [HW] Sony Programmable I/O Control Device driver See Documentation/sonypi.txt @@ -2475,8 +2478,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. topology= [S390] Format: {off | on} Specify if the kernel should make use of the cpu - topology informations if the hardware supports these. - The scheduler will make use of these informations and + topology information if the hardware supports this. + The scheduler will make use of this information and e.g. base its process migration decisions on it. Default is on. @@ -2529,8 +2532,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. reported either. unknown_nmi_panic - [X86] - Set unknown_nmi_panic=1 early on boot. + [X86] Cause panic on unknown NMI. usbcore.autosuspend= [USB] The autosuspend time delay (in seconds) used diff --git a/Documentation/kmemleak.txt b/Documentation/kmemleak.txt index 34f6638aa5ac..090e6ee04536 100644 --- a/Documentation/kmemleak.txt +++ b/Documentation/kmemleak.txt @@ -11,6 +11,7 @@ with the difference that the orphan objects are not freed but only reported via /sys/kernel/debug/kmemleak. A similar method is used by the Valgrind tool (memcheck --leak-check) to detect the memory leaks in user-space applications. +Kmemleak is supported on x86, arm, powerpc, sparc, sh, microblaze and tile. Usage ----- @@ -178,5 +179,4 @@ block doesn't need to be freed (some cases in the init_call functions), the pointer is calculated by other methods than the usual container_of macro or the pointer is stored in a location not scanned by kmemleak. -Page allocations and ioremap are not tracked. Only the ARM and x86 -architectures are currently supported. +Page allocations and ioremap are not tracked. diff --git a/Documentation/laptops/asus-laptop.txt b/Documentation/laptops/asus-laptop.txt index c1c5be84e4b1..803e51f6768b 100644 --- a/Documentation/laptops/asus-laptop.txt +++ b/Documentation/laptops/asus-laptop.txt @@ -61,7 +61,7 @@ Usage Hotkeys are also reported as input keys (like keyboards) you can check which key are supported using "xev" under X11. - You can get informations on the version of your DSDT table by reading the + You can get information on the version of your DSDT table by reading the /sys/devices/platform/asus-laptop/infos entry. If you have a question or a bug report to do, please include the output of this entry. @@ -178,7 +178,7 @@ LED display ----------- Some models like the W1N have a LED display that can be used to display - several informations. + several items of information. LED display works for the following models: W1000N diff --git a/Documentation/leds/00-INDEX b/Documentation/leds/00-INDEX new file mode 100644 index 000000000000..29f481df32c7 --- /dev/null +++ b/Documentation/leds/00-INDEX @@ -0,0 +1,8 @@ +leds-class.txt + - documents LED handling under Linux. +leds-lp3944.txt + - notes on how to use the leds-lp3944 driver. +leds-lp5521.txt + - notes on how to use the leds-lp5521 driver. +leds-lp5523.txt + - notes on how to use the leds-lp5523 driver. diff --git a/Documentation/leds-class.txt b/Documentation/leds/leds-class.txt index 58b266bd1846..4996586e27e8 100644 --- a/Documentation/leds-class.txt +++ b/Documentation/leds/leds-class.txt @@ -95,4 +95,3 @@ There are a number of cases where a trigger might only be mappable to a particular LED (ACPI?). The addition of triggers provided by the LED driver should cover this option and be possible to add without breaking the current interface. - diff --git a/Documentation/leds-lp3944.txt b/Documentation/leds/leds-lp3944.txt index c6eda18b15ef..c6eda18b15ef 100644 --- a/Documentation/leds-lp3944.txt +++ b/Documentation/leds/leds-lp3944.txt diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt index 18afcd8afd51..ee496eb2f4a6 100644 --- a/Documentation/networking/batman-adv.txt +++ b/Documentation/networking/batman-adv.txt @@ -72,7 +72,7 @@ folder: # fragmentation gw_sel_class vis_mode -There is a special folder for debugging informations: +There is a special folder for debugging information: # ls /sys/kernel/debug/batman_adv/bat0/ # gateways socket transtable_global vis_data diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt index 86f9f74b2b34..efe998becc5b 100644 --- a/Documentation/s390/Debugging390.txt +++ b/Documentation/s390/Debugging390.txt @@ -2273,7 +2273,7 @@ IP forwarding is on. There is a lot of useful info in here best found by going in & having a look around, so I'll take you through some entries I consider important. -All the processes running on the machine have there own entry defined by +All the processes running on the machine have their own entry defined by /proc/<pid> So lets have a look at the init process cd /proc/1 diff --git a/Documentation/scheduler/sched-domains.txt b/Documentation/scheduler/sched-domains.txt index 373ceacc367e..b7ee379b651b 100644 --- a/Documentation/scheduler/sched-domains.txt +++ b/Documentation/scheduler/sched-domains.txt @@ -1,8 +1,7 @@ -Each CPU has a "base" scheduling domain (struct sched_domain). These are -accessed via cpu_sched_domain(i) and this_sched_domain() macros. The domain +Each CPU has a "base" scheduling domain (struct sched_domain). The domain hierarchy is built from these base domains via the ->parent pointer. ->parent -MUST be NULL terminated, and domain structures should be per-CPU as they -are locklessly updated. +MUST be NULL terminated, and domain structures should be per-CPU as they are +locklessly updated. Each scheduling domain spans a number of CPUs (stored in the ->span field). A domain's span MUST be a superset of it child's span (this restriction could @@ -26,11 +25,26 @@ is treated as one entity. The load of a group is defined as the sum of the load of each of its member CPUs, and only when the load of a group becomes out of balance are tasks moved between groups. -In kernel/sched.c, rebalance_tick is run periodically on each CPU. This -function takes its CPU's base sched domain and checks to see if has reached -its rebalance interval. If so, then it will run load_balance on that domain. -rebalance_tick then checks the parent sched_domain (if it exists), and the -parent of the parent and so forth. +In kernel/sched.c, trigger_load_balance() is run periodically on each CPU +through scheduler_tick(). It raises a softirq after the next regularly scheduled +rebalancing event for the current runqueue has arrived. The actual load +balancing workhorse, run_rebalance_domains()->rebalance_domains(), is then run +in softirq context (SCHED_SOFTIRQ). + +The latter function takes two arguments: the current CPU and whether it was idle +at the time the scheduler_tick() happened and iterates over all sched domains +our CPU is on, starting from its base domain and going up the ->parent chain. +While doing that, it checks to see if the current domain has exhausted its +rebalance interval. If so, it runs load_balance() on that domain. It then checks +the parent sched_domain (if it exists), and the parent of the parent and so +forth. + +Initially, load_balance() finds the busiest group in the current sched domain. +If it succeeds, it looks for the busiest runqueue of all the CPUs' runqueues in +that group. If it manages to find such a runqueue, it locks both our initial +CPU's runqueue and the newly found busiest one and starts moving tasks from it +to our runqueue. The exact number of tasks amounts to an imbalance previously +computed while iterating over this sched domain's groups. *** Implementing sched domains *** The "base" domain will "span" the first level of the hierarchy. In the case diff --git a/Documentation/scsi/sym53c8xx_2.txt b/Documentation/scsi/sym53c8xx_2.txt index 6f63b7989679..6af8f7a7770f 100644 --- a/Documentation/scsi/sym53c8xx_2.txt +++ b/Documentation/scsi/sym53c8xx_2.txt @@ -285,7 +285,7 @@ from the driver. 7. Profiling information -This driver does not provide profiling informations as did its predecessors. +This driver does not provide profiling information as did its predecessors. This feature was not this useful and added complexity to the code. As the driver code got more complex, I have decided to remove everything that didn't seem actually useful. diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 3c1eddd9fcc7..181ba5b87cef 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -2229,7 +2229,7 @@ Proc interfaces (/proc/asound) /proc/asound/card#/pcm#[cp]/oss ------------------------------- - String "erase" - erase all additional informations about OSS applications + String "erase" - erase all additional information about OSS applications String "<app_name> <fragments> <fragment_size> [<options>]" <app_name> - name of application with (higher priority) or without path diff --git a/Documentation/sound/oss/AudioExcelDSP16 b/Documentation/sound/oss/AudioExcelDSP16 index c0f08922993b..e0dc0641b480 100644 --- a/Documentation/sound/oss/AudioExcelDSP16 +++ b/Documentation/sound/oss/AudioExcelDSP16 @@ -1,10 +1,10 @@ Driver ------ -Informations about Audio Excel DSP 16 driver can be found in the source +Information about Audio Excel DSP 16 driver can be found in the source file aedsp16.c Please, read the head of the source before using it. It contain useful -informations. +information. Configuration ------------- @@ -68,7 +68,7 @@ Sound cards supported This driver supports the SC-6000 and SC-6600 based Gallant's sound card. It don't support the Audio Excel DSP 16 III (try the SC-6600 code). I'm working on the III version of the card: if someone have useful -informations about it, please let me know. +information about it, please let me know. For all the non-supported audio cards, you have to boot MS-DOS (or WIN95) activating the audio card with the MS-DOS device driver, then you have to <ctrl>-<alt>-<del> and boot Linux. diff --git a/Documentation/sound/oss/README.ymfsb b/Documentation/sound/oss/README.ymfsb index af8a7d3a4e8e..b6b77906b58d 100644 --- a/Documentation/sound/oss/README.ymfsb +++ b/Documentation/sound/oss/README.ymfsb @@ -5,7 +5,7 @@ FIRST OF ALL ============ This code references YAMAHA's sample codes and data sheets. - I respect and thank for all people they made open the informations + I respect and thank for all people they made open the information about YMF7xx cards. And this codes heavily based on Jeff Garzik <jgarzik@pobox.com>'s diff --git a/Documentation/video4linux/bttv/Insmod-options b/Documentation/video4linux/bttv/Insmod-options index bbe3ed667d91..14c065fa23ef 100644 --- a/Documentation/video4linux/bttv/Insmod-options +++ b/Documentation/video4linux/bttv/Insmod-options @@ -1,5 +1,5 @@ -Note: "modinfo <module>" prints various informations about a kernel +Note: "modinfo <module>" prints various information about a kernel module, among them a complete and up-to-date list of insmod options. This list tends to be outdated because it is updated manually ... diff --git a/Documentation/video4linux/bttv/Sound-FAQ b/Documentation/video4linux/bttv/Sound-FAQ index 1e6328f91083..bc5e41d5d77a 100644 --- a/Documentation/video4linux/bttv/Sound-FAQ +++ b/Documentation/video4linux/bttv/Sound-FAQ @@ -8,7 +8,7 @@ completely by the bt8xx chip, which is common on all boards. But sound is handled in slightly different ways on each board. To handle the grabber boards correctly, there is a array tvcards[] in -bttv-cards.c, which holds the informations required for each board. +bttv-cards.c, which holds the information required for each board. Sound will work only, if the correct entry is used (for video it often makes no difference). The bttv driver prints a line to the kernel log, telling which card type is used. Like this one: diff --git a/Documentation/video4linux/et61x251.txt b/Documentation/video4linux/et61x251.txt index 1247566c4de3..e0cdae491858 100644 --- a/Documentation/video4linux/et61x251.txt +++ b/Documentation/video4linux/et61x251.txt @@ -191,10 +191,10 @@ Syntax: <n> Description: Debugging information level, from 0 to 3: 0 = none (use carefully) 1 = critical errors - 2 = significant informations + 2 = significant information 3 = more verbose messages Level 3 is useful for testing only, when only one device - is used at the same time. It also shows some more informations + is used at the same time. It also shows some more information about the hardware being detected. This module parameter can be changed at runtime thanks to the /sys filesystem interface. Default: 2 diff --git a/Documentation/video4linux/sn9c102.txt b/Documentation/video4linux/sn9c102.txt index 73de4050d637..b4f67040403a 100644 --- a/Documentation/video4linux/sn9c102.txt +++ b/Documentation/video4linux/sn9c102.txt @@ -214,10 +214,10 @@ Syntax: <n> Description: Debugging information level, from 0 to 3: 0 = none (use carefully) 1 = critical errors - 2 = significant informations + 2 = significant information 3 = more verbose messages Level 3 is useful for testing only. It also shows some more - informations about the hardware being detected. + information about the hardware being detected. This parameter can be changed at runtime thanks to the /sys filesystem interface. Default: 2 diff --git a/Documentation/video4linux/w9968cf.txt b/Documentation/video4linux/w9968cf.txt index 05138e8aea07..9649450f3b90 100644 --- a/Documentation/video4linux/w9968cf.txt +++ b/Documentation/video4linux/w9968cf.txt @@ -413,7 +413,7 @@ Syntax: <n> Description: Debugging information level, from 0 to 6: 0 = none (use carefully) 1 = critical errors - 2 = significant informations + 2 = significant information 3 = configuration or general messages 4 = warnings 5 = called functions diff --git a/Documentation/video4linux/zc0301.txt b/Documentation/video4linux/zc0301.txt index befdfdacdc5b..b41c83cf09f4 100644 --- a/Documentation/video4linux/zc0301.txt +++ b/Documentation/video4linux/zc0301.txt @@ -181,10 +181,10 @@ Syntax: <n> Description: Debugging information level, from 0 to 3: 0 = none (use carefully) 1 = critical errors - 2 = significant informations + 2 = significant information 3 = more verbose messages Level 3 is useful for testing only, when only one device - is used at the same time. It also shows some more informations + is used at the same time. It also shows some information about the hardware being detected. This module parameter can be changed at runtime thanks to the /sys filesystem interface. Default: 2 @@ -261,7 +261,7 @@ the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. 11. Credits =========== -- Informations about the chip internals needed to enable the I2C protocol have +- Information about the chip internals needed to enable the I2C protocol have been taken from the documentation of the ZC030x Video4Linux1 driver written by Andrew Birkett <andy@nobugs.org>; - The initialization values of the ZC0301 controller connected to the PAS202BCB @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 39 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index bd4160c57196..9808998cc073 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -12,7 +12,6 @@ config ALPHA select GENERIC_IRQ_PROBE select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW - select GENERIC_HARDIRQS_NO_DEPRECATED help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7c0effb69fc7..5b9f78b570e8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -366,6 +366,7 @@ config ARCH_MXC select GENERIC_CLOCKEVENTS select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select HAVE_SCHED_CLOCK help Support for Freescale MXC/iMX-based family of processors diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 84ac4d656310..adf583cd0c35 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -21,20 +21,12 @@ #if defined(CONFIG_DEBUG_ICEDCC) -#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) .macro loadsp, rb, tmp .endm .macro writeb, ch, rb mcr p14, 0, \ch, c0, c5, 0 .endm -#elif defined(CONFIG_CPU_V7) - .macro loadsp, rb, tmp - .endm - .macro writeb, ch, rb -wait: mrc p14, 0, pc, c0, c1, 0 - bcs wait - mcr p14, 0, \ch, c0, c5, 0 - .endm #elif defined(CONFIG_CPU_XSCALE) .macro loadsp, rb, tmp .endm diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 4657e877bf8f..2df38263124c 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -36,7 +36,7 @@ extern void error(char *x); #ifdef CONFIG_DEBUG_ICEDCC -#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) static void icedcc_putc(int ch) { @@ -52,16 +52,6 @@ static void icedcc_putc(int ch) asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); } -#elif defined(CONFIG_CPU_V7) - -static void icedcc_putc(int ch) -{ - asm( - "wait: mrc p14, 0, pc, c0, c1, 0 \n\ - bcs wait \n\ - mcr p14, 0, %0, c0, c5, 0 " - : : "r" (ch)); -} #elif defined(CONFIG_CPU_XSCALE) diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h index 833306ee9e7f..ea297ac70bc6 100644 --- a/arch/arm/include/asm/mach/udc_pxa2xx.h +++ b/arch/arm/include/asm/mach/udc_pxa2xx.h @@ -20,8 +20,6 @@ struct pxa2xx_udc_mach_info { * VBUS IRQ and omit the methods above. Store the GPIO number * here. Note that sometimes the signals go through inverters... */ - bool gpio_vbus_inverted; - int gpio_vbus; /* high == vbus present */ bool gpio_pullup_inverted; int gpio_pullup; /* high == pullup activated */ }; diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index d2d983be096d..bcd66e00bdbe 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -25,7 +25,7 @@ .macro addruart, rp, rv .endm -#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) +#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) .macro senduart, rd, rx mcr p14, 0, \rd, c0, c5, 0 @@ -49,23 +49,6 @@ 1002: .endm -#elif defined(CONFIG_CPU_V7) - - .macro senduart, rd, rx - mcr p14, 0, \rd, c0, c5, 0 - .endm - - .macro busyuart, rd, rx -busy: mrc p14, 0, pc, c0, c1, 0 - bcs busy - .endm - - .macro waituart, rd, rx -wait: mrc p14, 0, pc, c0, c1, 0 - bcs wait - - .endm - #elif defined(CONFIG_CPU_XSCALE) .macro senduart, rd, rx diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 052b509e2d5f..1bec8b5f22f0 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c @@ -338,7 +338,7 @@ static struct miscdevice etb_miscdev = { .fops = &etb_fops, }; -static int __init etb_probe(struct amba_device *dev, const struct amba_id *id) +static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id) { struct tracectx *t = &tracer; int ret = 0; @@ -530,7 +530,7 @@ static ssize_t trace_mode_store(struct kobject *kobj, static struct kobj_attribute trace_mode_attr = __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store); -static int __init etm_probe(struct amba_device *dev, const struct amba_id *id) +static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id) { struct tracectx *t = &tracer; int ret = 0; diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c index 8f6ed43861f1..23891317dc4b 100644 --- a/arch/arm/kernel/kprobes-decode.c +++ b/arch/arm/kernel/kprobes-decode.c @@ -594,7 +594,8 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) long cpsr = regs->ARM_cpsr; fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn); - regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */ + if (rn != 15) + regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */ rdv = fnr.r1; if (rd == 15) { @@ -622,10 +623,11 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs) long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd]; long rnv = (rn == 15) ? iaddr + 8 : regs->uregs[rn]; long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ + long rnv_wb; - /* Save Rn in case of writeback. */ - regs->uregs[rn] = - insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn); + rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn); + if (rn != 15) + regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */ } static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs) diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 22e194eb8536..69cfee0fe00f 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -79,6 +79,7 @@ struct arm_pmu { void (*write_counter)(int idx, u32 val); void (*start)(void); void (*stop)(void); + void (*reset)(void *); const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX]; @@ -204,11 +205,9 @@ armpmu_event_set_period(struct perf_event *event, static u64 armpmu_event_update(struct perf_event *event, struct hw_perf_event *hwc, - int idx) + int idx, int overflow) { - int shift = 64 - 32; - s64 prev_raw_count, new_raw_count; - u64 delta; + u64 delta, prev_raw_count, new_raw_count; again: prev_raw_count = local64_read(&hwc->prev_count); @@ -218,8 +217,13 @@ again: new_raw_count) != prev_raw_count) goto again; - delta = (new_raw_count << shift) - (prev_raw_count << shift); - delta >>= shift; + new_raw_count &= armpmu->max_period; + prev_raw_count &= armpmu->max_period; + + if (overflow) + delta = armpmu->max_period - prev_raw_count + new_raw_count; + else + delta = new_raw_count - prev_raw_count; local64_add(delta, &event->count); local64_sub(delta, &hwc->period_left); @@ -236,7 +240,7 @@ armpmu_read(struct perf_event *event) if (hwc->idx < 0) return; - armpmu_event_update(event, hwc, hwc->idx); + armpmu_event_update(event, hwc, hwc->idx, 0); } static void @@ -254,7 +258,7 @@ armpmu_stop(struct perf_event *event, int flags) if (!(hwc->state & PERF_HES_STOPPED)) { armpmu->disable(hwc, hwc->idx); barrier(); /* why? */ - armpmu_event_update(event, hwc, hwc->idx); + armpmu_event_update(event, hwc, hwc->idx, 0); hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; } } @@ -624,6 +628,19 @@ static struct pmu pmu = { #include "perf_event_v6.c" #include "perf_event_v7.c" +/* + * Ensure the PMU has sane values out of reset. + * This requires SMP to be available, so exists as a separate initcall. + */ +static int __init +armpmu_reset(void) +{ + if (armpmu && armpmu->reset) + return on_each_cpu(armpmu->reset, NULL, 1); + return 0; +} +arch_initcall(armpmu_reset); + static int __init init_hw_perf_events(void) { diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c index 6fc2d228db55..f1e8dd94afe8 100644 --- a/arch/arm/kernel/perf_event_v6.c +++ b/arch/arm/kernel/perf_event_v6.c @@ -474,7 +474,7 @@ armv6pmu_handle_irq(int irq_num, continue; hwc = &event->hw; - armpmu_event_update(event, hwc, idx); + armpmu_event_update(event, hwc, idx, 1); data.period = event->hw.last_period; if (!armpmu_event_set_period(event, hwc, idx)) continue; diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 2e1402556fa0..4960686afb58 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -466,6 +466,7 @@ static inline unsigned long armv7_pmnc_read(void) static inline void armv7_pmnc_write(unsigned long val) { val &= ARMV7_PMNC_MASK; + isb(); asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val)); } @@ -502,6 +503,7 @@ static inline int armv7_pmnc_select_counter(unsigned int idx) val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK; asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); + isb(); return idx; } @@ -780,7 +782,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev) continue; hwc = &event->hw; - armpmu_event_update(event, hwc, idx); + armpmu_event_update(event, hwc, idx, 1); data.period = event->hw.last_period; if (!armpmu_event_set_period(event, hwc, idx)) continue; @@ -847,6 +849,18 @@ static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc, } } +static void armv7pmu_reset(void *info) +{ + u32 idx, nb_cnt = armpmu->num_events; + + /* The counter and interrupt enable registers are unknown at reset. */ + for (idx = 1; idx < nb_cnt; ++idx) + armv7pmu_disable_event(NULL, idx); + + /* Initialize & Reset PMNC: C and P bits */ + armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); +} + static struct arm_pmu armv7pmu = { .handle_irq = armv7pmu_handle_irq, .enable = armv7pmu_enable_event, @@ -856,17 +870,15 @@ static struct arm_pmu armv7pmu = { .get_event_idx = armv7pmu_get_event_idx, .start = armv7pmu_start, .stop = armv7pmu_stop, + .reset = armv7pmu_reset, .raw_event_mask = 0xFF, .max_period = (1LLU << 32) - 1, }; -static u32 __init armv7_reset_read_pmnc(void) +static u32 __init armv7_read_num_pmnc_events(void) { u32 nb_cnt; - /* Initialize & Reset PMNC: C and P bits */ - armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C); - /* Read the nb of CNTx counters supported from PMNC */ nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; @@ -880,7 +892,7 @@ static const struct arm_pmu *__init armv7_a8_pmu_init(void) armv7pmu.name = "ARMv7 Cortex-A8"; armv7pmu.cache_map = &armv7_a8_perf_cache_map; armv7pmu.event_map = &armv7_a8_perf_map; - armv7pmu.num_events = armv7_reset_read_pmnc(); + armv7pmu.num_events = armv7_read_num_pmnc_events(); return &armv7pmu; } @@ -890,7 +902,7 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void) armv7pmu.name = "ARMv7 Cortex-A9"; armv7pmu.cache_map = &armv7_a9_perf_cache_map; armv7pmu.event_map = &armv7_a9_perf_map; - armv7pmu.num_events = armv7_reset_read_pmnc(); + armv7pmu.num_events = armv7_read_num_pmnc_events(); return &armv7pmu; } #else diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c index 28cd3b025bc3..39affbe4fdb2 100644 --- a/arch/arm/kernel/perf_event_xscale.c +++ b/arch/arm/kernel/perf_event_xscale.c @@ -246,7 +246,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev) continue; hwc = &event->hw; - armpmu_event_update(event, hwc, idx); + armpmu_event_update(event, hwc, idx, 1); data.period = event->hw.last_period; if (!armpmu_event_set_period(event, hwc, idx)) continue; @@ -578,7 +578,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev) continue; hwc = &event->hw; - armpmu_event_update(event, hwc, idx); + armpmu_event_update(event, hwc, idx, 1); data.period = event->hw.last_period; if (!armpmu_event_set_period(event, hwc, idx)) continue; diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index bfad698a02e7..6398ead9d1c0 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S @@ -119,11 +119,19 @@ ENTRY(cpu_resume) #else ldr r0, sleep_save_sp @ stack phys addr #endif - msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off + setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off #ifdef MULTI_CPU - ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn + @ load v:p, stack, return fn, resume fn + ARM( ldmia r0!, {r1, sp, lr, pc} ) +THUMB( ldmia r0!, {r1, r2, r3, r4} ) +THUMB( mov sp, r2 ) +THUMB( mov lr, r3 ) +THUMB( bx r4 ) #else - ldmia r0!, {r1, sp, lr} @ load v:p, stack, return fn + @ load v:p, stack, return fn + ARM( ldmia r0!, {r1, sp, lr} ) +THUMB( ldmia r0!, {r1, r2, lr} ) +THUMB( mov sp, r2 ) b cpu_do_resume #endif ENDPROC(cpu_resume) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 5eec099e0c72..56b930a13443 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -255,6 +255,7 @@ config MACH_IMX27_VISSTRIM_M10 bool "Vista Silicon i.MX27 Visstrim_m10" select SOC_IMX27 select IMX_HAVE_PLATFORM_IMX_I2C + select IMX_HAVE_PLATFORM_IMX_SSI select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_MXC_MMC select IMX_HAVE_PLATFORM_MXC_EHCI diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c index cb705c28de02..6269053505f7 100644 --- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c +++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c @@ -34,6 +34,7 @@ #include <mach/mx25.h> #include <mach/imx-uart.h> #include <mach/audmux.h> +#include <mach/esdhc.h> #include "devices-imx25.h" @@ -242,6 +243,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = { .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE, }; +static struct esdhc_platform_data sd1_pdata = { + .cd_gpio = GPIO_SD1CD, + .wp_gpio = -EINVAL, +}; + /* * system init for baseboard usage. Will be called by cpuimx25 init. * @@ -275,7 +281,7 @@ void __init eukrea_mbimxsd25_baseboard_init(void) imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata); imx25_add_flexcan1(NULL); - imx25_add_sdhci_esdhc_imx(0, NULL); + imx25_add_sdhci_esdhc_imx(0, &sd1_pdata); gpio_request(GPIO_LED1, "LED1"); gpio_direction_output(GPIO_LED1, 1); diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c index 0a95063f6d32..17de0bf53c08 100644 --- a/arch/arm/mach-kirkwood/sheevaplug-setup.c +++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c @@ -58,6 +58,12 @@ static struct mvsdio_platform_data sheeva_esata_mvsdio_data = { static struct gpio_led sheevaplug_led_pins[] = { { + .name = "plug:red:misc", + .default_trigger = "none", + .gpio = 46, + .active_low = 1, + }, + { .name = "plug:green:health", .default_trigger = "default-on", .gpio = 49, @@ -80,6 +86,7 @@ static struct platform_device sheevaplug_leds = { static unsigned int sheevaplug_mpp_config[] __initdata = { MPP29_GPIO, /* USB Power Enable */ + MPP46_GPIO, /* LED Red */ MPP49_GPIO, /* LED */ 0 }; diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c index 80761474c0f8..2e288b38b4ad 100644 --- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c @@ -43,6 +43,7 @@ #include <mach/ipu.h> #include <mach/mx3fb.h> #include <mach/audmux.h> +#include <mach/esdhc.h> #include "devices-imx35.h" #include "devices.h" @@ -163,11 +164,14 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = { MX35_PAD_SD1_DATA1__ESDHC1_DAT1, MX35_PAD_SD1_DATA2__ESDHC1_DAT2, MX35_PAD_SD1_DATA3__ESDHC1_DAT3, + /* SD1 CD */ + MX35_PAD_LD18__GPIO3_24, }; #define GPIO_LED1 IMX_GPIO_NR(3, 29) #define GPIO_SWITCH1 IMX_GPIO_NR(3, 25) -#define GPIO_LCDPWR (4) +#define GPIO_LCDPWR IMX_GPIO_NR(1, 4) +#define GPIO_SD1CD IMX_GPIO_NR(3, 24) static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd, unsigned int power) @@ -254,6 +258,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = { .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE, }; +static struct esdhc_platform_data sd1_pdata = { + .cd_gpio = GPIO_SD1CD, + .wp_gpio = -EINVAL, +}; + /* * system init for baseboard usage. Will be called by cpuimx35 init. * @@ -289,7 +298,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void) imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata); imx35_add_flexcan1(NULL); - imx35_add_sdhci_esdhc_imx(0, NULL); + imx35_add_sdhci_esdhc_imx(0, &sd1_pdata); gpio_request(GPIO_LED1, "LED1"); gpio_direction_output(GPIO_LED1, 1); @@ -301,7 +310,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void) gpio_request(GPIO_LCDPWR, "LCDPWR"); gpio_direction_output(GPIO_LCDPWR, 1); - gpio_free(GPIO_LCDPWR); i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices, ARRAY_SIZE(eukrea_mbimxsd_i2c_devices)); diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c index b3ecfb22d241..036ba1a4704b 100644 --- a/arch/arm/mach-mx3/mach-pcm043.c +++ b/arch/arm/mach-mx3/mach-pcm043.c @@ -40,6 +40,7 @@ #include <mach/mx3fb.h> #include <mach/ulpi.h> #include <mach/audmux.h> +#include <mach/esdhc.h> #include "devices-imx35.h" #include "devices.h" @@ -217,11 +218,15 @@ static iomux_v3_cfg_t pcm043_pads[] = { MX35_PAD_SD1_DATA1__ESDHC1_DAT1, MX35_PAD_SD1_DATA2__ESDHC1_DAT2, MX35_PAD_SD1_DATA3__ESDHC1_DAT3, + MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */ + MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */ }; #define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31) #define AC97_GPIO_TXD IMX_GPIO_NR(2, 28) #define AC97_GPIO_RESET IMX_GPIO_NR(2, 0) +#define SD1_GPIO_WP IMX_GPIO_NR(2, 23) +#define SD1_GPIO_CD IMX_GPIO_NR(2, 24) static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97) { @@ -346,6 +351,11 @@ static int __init pcm043_otg_mode(char *options) } __setup("otg_mode=", pcm043_otg_mode); +static struct esdhc_platform_data sd1_pdata = { + .wp_gpio = SD1_GPIO_WP, + .cd_gpio = SD1_GPIO_CD, +}; + /* * Board specific initialization. */ @@ -395,7 +405,7 @@ static void __init pcm043_init(void) imx35_add_fsl_usb2_udc(&otg_device_pdata); imx35_add_flexcan1(NULL); - imx35_add_sdhci_esdhc_imx(0, NULL); + imx35_add_sdhci_esdhc_imx(0, &sd1_pdata); } static void __init pcm043_timer_init(void) diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig index 83ee08847d4d..159340da9191 100644 --- a/arch/arm/mach-mx5/Kconfig +++ b/arch/arm/mach-mx5/Kconfig @@ -165,6 +165,7 @@ config MACH_MX53_LOCO select IMX_HAVE_PLATFORM_IMX_I2C select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX + select IMX_HAVE_PLATFORM_GPIO_KEYS help Include support for MX53 LOCO platform. This includes specific configurations for the board and its peripherals. diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile index 4f63048be3ca..0b9338cec516 100644 --- a/arch/arm/mach-mx5/Makefile +++ b/arch/arm/mach-mx5/Makefile @@ -3,7 +3,7 @@ # # Object file lists. -obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o +obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o obj-$(CONFIG_SOC_IMX50) += mm-mx50.o obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index b2ecd194e76d..bea4e4135f9d 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -228,13 +228,12 @@ static inline void babbage_fec_reset(void) int ret; /* reset FEC PHY */ - ret = gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset"); + ret = gpio_request_one(BABBAGE_FEC_PHY_RESET, + GPIOF_OUT_INIT_LOW, "fec-phy-reset"); if (ret) { printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret); return; } - gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0); - gpio_set_value(BABBAGE_FEC_PHY_RESET, 0); msleep(1); gpio_set_value(BABBAGE_FEC_PHY_RESET, 1); } diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c index 7b5735c5ea59..2af3f43f74db 100644 --- a/arch/arm/mach-mx5/board-mx53_evk.c +++ b/arch/arm/mach-mx5/board-mx53_evk.c @@ -34,7 +34,7 @@ #include <mach/imx-uart.h> #include <mach/iomux-mx53.h> -#define SMD_FEC_PHY_RST IMX_GPIO_NR(7, 6) +#define MX53_EVK_FEC_PHY_RST IMX_GPIO_NR(7, 6) #define EVK_ECSPI1_CS0 IMX_GPIO_NR(2, 30) #define EVK_ECSPI1_CS1 IMX_GPIO_NR(3, 19) @@ -82,15 +82,14 @@ static inline void mx53_evk_fec_reset(void) int ret; /* reset FEC PHY */ - ret = gpio_request(SMD_FEC_PHY_RST, "fec-phy-reset"); + ret = gpio_request_one(MX53_EVK_FEC_PHY_RST, GPIOF_OUT_INIT_LOW, + "fec-phy-reset"); if (ret) { printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret); return; } - gpio_direction_output(SMD_FEC_PHY_RST, 0); - gpio_set_value(SMD_FEC_PHY_RST, 0); msleep(1); - gpio_set_value(SMD_FEC_PHY_RST, 1); + gpio_set_value(MX53_EVK_FEC_PHY_RST, 1); } static struct fec_platform_data mx53_evk_fec_pdata = { diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c index 0a18f8d23eb0..10a1bea10548 100644 --- a/arch/arm/mach-mx5/board-mx53_loco.c +++ b/arch/arm/mach-mx5/board-mx53_loco.c @@ -36,6 +36,9 @@ #include "crm_regs.h" #include "devices-imx53.h" +#define MX53_LOCO_POWER IMX_GPIO_NR(1, 8) +#define MX53_LOCO_UI1 IMX_GPIO_NR(2, 14) +#define MX53_LOCO_UI2 IMX_GPIO_NR(2, 15) #define LOCO_FEC_PHY_RST IMX_GPIO_NR(7, 6) static iomux_v3_cfg_t mx53_loco_pads[] = { @@ -180,6 +183,27 @@ static iomux_v3_cfg_t mx53_loco_pads[] = { MX53_PAD_GPIO_8__GPIO1_8, }; +#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \ +{ \ + .gpio = gpio_num, \ + .type = EV_KEY, \ + .code = ev_code, \ + .active_low = act_low, \ + .desc = "btn " descr, \ + .wakeup = wake, \ +} + +static const struct gpio_keys_button loco_buttons[] __initconst = { + GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0), + GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0), + GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0), +}; + +static const struct gpio_keys_platform_data loco_button_data __initconst = { + .buttons = loco_buttons, + .nbuttons = ARRAY_SIZE(loco_buttons), +}; + static inline void mx53_loco_fec_reset(void) { int ret; @@ -215,6 +239,7 @@ static void __init mx53_loco_board_init(void) imx53_add_imx_i2c(1, &mx53_loco_i2c_data); imx53_add_sdhci_esdhc_imx(0, NULL); imx53_add_sdhci_esdhc_imx(2, NULL); + imx_add_gpio_keys(&loco_button_data); } static void __init mx53_loco_timer_init(void) diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c index 652ace413825..fdbc05ed5513 100644 --- a/arch/arm/mach-mx5/clock-mx51-mx53.c +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c @@ -865,6 +865,13 @@ static struct clk aips_tz2_clk = { .disable = _clk_ccgr_disable_inwait, }; +static struct clk gpc_dvfs_clk = { + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET, + .enable = _clk_ccgr_enable, + .disable = _clk_ccgr_disable, +}; + static struct clk gpt_32k_clk = { .id = 0, .parent = &ckil_clk, @@ -1448,6 +1455,7 @@ static struct clk_lookup mx51_lookups[] = { _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk) _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk) _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk) + _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk) }; static struct clk_lookup mx53_lookups[] = { @@ -1511,6 +1519,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, clk_enable(&iim_clk); mx51_revision(); clk_disable(&iim_clk); + mx51_display_revision(); /* move usb_phy_clk to 24MHz */ clk_set_parent(&usb_phy1_clk, &osc_clk); diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c index df46b5e60857..472bdfab2e55 100644 --- a/arch/arm/mach-mx5/cpu.c +++ b/arch/arm/mach-mx5/cpu.c @@ -21,6 +21,7 @@ static int cpu_silicon_rev = -1; #define IIM_SREV 0x24 +#define MX50_HW_ADADIG_DIGPROG 0xB0 static int get_mx51_srev(void) { @@ -51,6 +52,26 @@ int mx51_revision(void) } EXPORT_SYMBOL(mx51_revision); +void mx51_display_revision(void) +{ + int rev; + char *srev; + rev = mx51_revision(); + + switch (rev) { + case IMX_CHIP_REVISION_2_0: + srev = IMX_CHIP_REVISION_2_0_STRING; + break; + case IMX_CHIP_REVISION_3_0: + srev = IMX_CHIP_REVISION_3_0_STRING; + break; + default: + srev = IMX_CHIP_REVISION_UNKNOWN_STRING; + } + printk(KERN_INFO "CPU identified as i.MX51, silicon rev %s\n", srev); +} +EXPORT_SYMBOL(mx51_display_revision); + #ifdef CONFIG_NEON /* @@ -107,6 +128,44 @@ int mx53_revision(void) } EXPORT_SYMBOL(mx53_revision); +static int get_mx50_srev(void) +{ + void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K); + u32 rev; + + if (!anatop) { + cpu_silicon_rev = -EINVAL; + return 0; + } + + rev = readl(anatop + MX50_HW_ADADIG_DIGPROG); + rev &= 0xff; + + iounmap(anatop); + if (rev == 0x0) + return IMX_CHIP_REVISION_1_0; + else if (rev == 0x1) + return IMX_CHIP_REVISION_1_1; + return 0; +} + +/* + * Returns: + * the silicon revision of the cpu + * -EINVAL - not a mx50 + */ +int mx50_revision(void) +{ + if (!cpu_is_mx50()) + return -EINVAL; + + if (cpu_silicon_rev == -1) + cpu_silicon_rev = get_mx50_srev(); + + return cpu_silicon_rev; +} +EXPORT_SYMBOL(mx50_revision); + static int __init post_cpu_init(void) { unsigned int reg; diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c index c372a4373691..e6c1119c20ae 100644 --- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c +++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c @@ -67,6 +67,10 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = { MX51_PAD_SD1_DATA1__SD1_DATA1, MX51_PAD_SD1_DATA2__SD1_DATA2, MX51_PAD_SD1_DATA3__SD1_DATA3, + /* SD1 CD */ + _MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP | + PAD_CTL_PKE | PAD_CTL_SRE_FAST | + PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS), }; #define GPIO_LED1 IMX_GPIO_NR(3, 30) diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-mx5/mx51_efika.c index 868af8f435fa..d0c7075937cf 100644 --- a/arch/arm/mach-mx5/mx51_efika.c +++ b/arch/arm/mach-mx5/mx51_efika.c @@ -42,7 +42,6 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/time.h> -#include <asm/mach-types.h> #include "devices-imx51.h" #include "devices.h" diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c new file mode 100644 index 000000000000..76ae8dc33e00 --- /dev/null +++ b/arch/arm/mach-mx5/system.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include <linux/platform_device.h> +#include <linux/io.h> +#include <mach/hardware.h> +#include "crm_regs.h" + +/* set cpu low power mode before WFI instruction. This function is called + * mx5 because it can be used for mx50, mx51, and mx53.*/ +void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) +{ + u32 plat_lpc, arm_srpgcr, ccm_clpcr; + u32 empgc0, empgc1; + int stop_mode = 0; + + /* always allow platform to issue a deep sleep mode request */ + plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) & + ~(MXC_CORTEXA8_PLAT_LPC_DSM); + ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); + arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); + empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); + empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); + + switch (mode) { + case WAIT_CLOCKED: + break; + case WAIT_UNCLOCKED: + ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET; + break; + case WAIT_UNCLOCKED_POWER_OFF: + case STOP_POWER_OFF: + plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM + | MXC_CORTEXA8_PLAT_LPC_DBG_DSM; + if (mode == WAIT_UNCLOCKED_POWER_OFF) { + ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET; + ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY; + ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS; + stop_mode = 0; + } else { + ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET; + ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET; + ccm_clpcr |= MXC_CCM_CLPCR_VSTBY; + ccm_clpcr |= MXC_CCM_CLPCR_SBYOS; + stop_mode = 1; + } + arm_srpgcr |= MXC_SRPGCR_PCR; + + if (tzic_enable_wake(1) != 0) + return; + break; + case STOP_POWER_ON: + ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET; + break; + default: + printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode); + return; + } + + __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC); + __raw_writel(ccm_clpcr, MXC_CCM_CLPCR); + __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR); + + /* Enable NEON SRPG for all but MX50TO1.0. */ + if (mx50_revision() != IMX_CHIP_REVISION_1_0) + __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); + + if (stop_mode) { + empgc0 |= MXC_SRPGCR_PCR; + empgc1 |= MXC_SRPGCR_PCR; + + __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR); + __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR); + } +} diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index 4f6f174af6c8..4522fbb235d5 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -22,6 +22,7 @@ config MACH_MX23EVK select SOC_IMX23 select MXS_HAVE_AMBA_DUART select MXS_HAVE_PLATFORM_AUART + select MXS_HAVE_PLATFORM_MXS_MMC select MXS_HAVE_PLATFORM_MXSFB default y help @@ -35,6 +36,7 @@ config MACH_MX28EVK select MXS_HAVE_PLATFORM_AUART select MXS_HAVE_PLATFORM_FEC select MXS_HAVE_PLATFORM_FLEXCAN + select MXS_HAVE_PLATFORM_MXS_MMC select MXS_HAVE_PLATFORM_MXSFB select MXS_OCOTP default y diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c index d133c7f30940..c3577ea789ac 100644 --- a/arch/arm/mach-mxs/clock-mx23.c +++ b/arch/arm/mach-mxs/clock-mx23.c @@ -521,6 +521,15 @@ static int clk_misc_init(void) __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET); + /* + * 480 MHz seems too high to be ssp clock source directly, + * so set frac to get a 288 MHz ref_io. + */ + reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC); + reg &= ~BM_CLKCTRL_FRAC_IOFRAC; + reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC; + __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC); + return 0; } @@ -528,6 +537,12 @@ int __init mx23_clocks_init(void) { clk_misc_init(); + /* + * source ssp clock from ref_io than ref_xtal, + * as ref_xtal only provides 24 MHz as maximum. + */ + clk_set_parent(&ssp_clk, &ref_io_clk); + clk_enable(&cpu_clk); clk_enable(&hbus_clk); clk_enable(&xbus_clk); diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c index 5e489a2b2023..1ad97fed1e94 100644 --- a/arch/arm/mach-mxs/clock-mx28.c +++ b/arch/arm/mach-mxs/clock-mx28.c @@ -618,6 +618,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("pll2", NULL, pll2_clk) _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk) _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk) + _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk) + _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk) _REGISTER_CLOCK("flexcan.0", NULL, can0_clk) _REGISTER_CLOCK("flexcan.1", NULL, can1_clk) _REGISTER_CLOCK(NULL, "usb0", usb0_clk) @@ -737,6 +739,15 @@ static int clk_misc_init(void) reg |= BM_CLKCTRL_ENET_CLK_OUT_EN; __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET); + /* + * 480 MHz seems too high to be ssp clock source directly, + * so set frac0 to get a 288 MHz ref_io0. + */ + reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0); + reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC; + reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC; + __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0); + return 0; } @@ -744,6 +755,13 @@ int __init mx28_clocks_init(void) { clk_misc_init(); + /* + * source ssp clock from ref_io0 than ref_xtal, + * as ref_xtal only provides 24 MHz as maximum. + */ + clk_set_parent(&ssp0_clk, &ref_io0_clk); + clk_set_parent(&ssp1_clk, &ref_io0_clk); + clk_enable(&cpu_clk); clk_enable(&hbus_clk); clk_enable(&xbus_clk); diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h index c7e14f4e3669..c6f345febd39 100644 --- a/arch/arm/mach-mxs/devices-mx23.h +++ b/arch/arm/mach-mxs/devices-mx23.h @@ -21,6 +21,10 @@ extern const struct mxs_auart_data mx23_auart_data[] __initconst; #define mx23_add_auart0() mx23_add_auart(0) #define mx23_add_auart1() mx23_add_auart(1) +extern const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst; +#define mx23_add_mxs_mmc(id, pdata) \ + mxs_add_mxs_mmc(&mx23_mxs_mmc_data[id], pdata) + #define mx23_add_mxs_pwm(id) mxs_add_mxs_pwm(MX23_PWM_BASE_ADDR, id) struct platform_device *__init mx23_add_mxsfb( diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h index 9d08555c4cf0..c473eddce8cf 100644 --- a/arch/arm/mach-mxs/devices-mx28.h +++ b/arch/arm/mach-mxs/devices-mx28.h @@ -37,6 +37,10 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst; extern const struct mxs_i2c_data mx28_mxs_i2c_data[] __initconst; #define mx28_add_mxs_i2c(id) mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id]) +extern const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst; +#define mx28_add_mxs_mmc(id, pdata) \ + mxs_add_mxs_mmc(&mx28_mxs_mmc_data[id], pdata) + #define mx28_add_mxs_pwm(id) mxs_add_mxs_pwm(MX28_PWM_BASE_ADDR, id) struct platform_device *__init mx28_add_mxsfb( diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig index 1451ad060d82..acf9eea124c0 100644 --- a/arch/arm/mach-mxs/devices/Kconfig +++ b/arch/arm/mach-mxs/devices/Kconfig @@ -15,6 +15,9 @@ config MXS_HAVE_PLATFORM_FLEXCAN config MXS_HAVE_PLATFORM_MXS_I2C bool +config MXS_HAVE_PLATFORM_MXS_MMC + bool + config MXS_HAVE_PLATFORM_MXS_PWM bool diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile index 0d9bea30b0a2..324f2824d38d 100644 --- a/arch/arm/mach-mxs/devices/Makefile +++ b/arch/arm/mach-mxs/devices/Makefile @@ -4,5 +4,6 @@ obj-y += platform-dma.o obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o +obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c new file mode 100644 index 000000000000..382dacbeca21 --- /dev/null +++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 Pengutronix + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> + * + * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + */ + +#include <linux/compiler.h> +#include <linux/err.h> +#include <linux/init.h> + +#include <mach/mx23.h> +#include <mach/mx28.h> +#include <mach/devices-common.h> + +#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid) \ + { \ + .id = _id, \ + .iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \ + .dma = soc ## _DMA_SSP ## hwid, \ + .irq_err = soc ## _INT_SSP ## hwid ## _ERROR, \ + .irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \ + } + +#define mxs_mxs_mmc_data_entry(soc, _id, hwid) \ + [_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid) + + +#ifdef CONFIG_SOC_IMX23 +const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = { + mxs_mxs_mmc_data_entry(MX23, 0, 1), + mxs_mxs_mmc_data_entry(MX23, 1, 2), +}; +#endif + +#ifdef CONFIG_SOC_IMX28 +const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = { + mxs_mxs_mmc_data_entry(MX28, 0, 0), + mxs_mxs_mmc_data_entry(MX28, 1, 1), +}; +#endif + +struct platform_device *__init mxs_add_mxs_mmc( + const struct mxs_mxs_mmc_data *data, + const struct mxs_mmc_platform_data *pdata) +{ + struct resource res[] = { + { + .start = data->iobase, + .end = data->iobase + SZ_8K - 1, + .flags = IORESOURCE_MEM, + }, { + .start = data->dma, + .end = data->dma, + .flags = IORESOURCE_DMA, + }, { + .start = data->irq_err, + .end = data->irq_err, + .flags = IORESOURCE_IRQ, + }, { + .start = data->irq_dma, + .end = data->irq_dma, + .flags = IORESOURCE_IRQ, + }, + }; + + return mxs_add_platform_device("mxs-mmc", data->id, + res, ARRAY_SIZE(res), pdata, sizeof(*pdata)); +} diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h index 71f24484b044..c5137f14c364 100644 --- a/arch/arm/mach-mxs/include/mach/devices-common.h +++ b/arch/arm/mach-mxs/include/mach/devices-common.h @@ -73,6 +73,19 @@ struct mxs_i2c_data { }; struct platform_device * __init mxs_add_mxs_i2c(const struct mxs_i2c_data *data); +/* mmc */ +#include <mach/mmc.h> +struct mxs_mxs_mmc_data { + int id; + resource_size_t iobase; + resource_size_t dma; + resource_size_t irq_err; + resource_size_t irq_dma; +}; +struct platform_device *__init mxs_add_mxs_mmc( + const struct mxs_mxs_mmc_data *data, + const struct mxs_mmc_platform_data *pdata); + /* pwm */ struct platform_device *__init mxs_add_mxs_pwm( resource_size_t iobase, int id); diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c index a66994f0518f..214e5b641bbc 100644 --- a/arch/arm/mach-mxs/mach-mx23evk.c +++ b/arch/arm/mach-mxs/mach-mx23evk.c @@ -28,6 +28,8 @@ #define MX23EVK_LCD_ENABLE MXS_GPIO_NR(1, 18) #define MX23EVK_BL_ENABLE MXS_GPIO_NR(1, 28) +#define MX23EVK_MMC0_WRITE_PROTECT MXS_GPIO_NR(1, 30) +#define MX23EVK_MMC0_SLOT_POWER MXS_GPIO_NR(1, 29) static const iomux_cfg_t mx23evk_pads[] __initconst = { /* duart */ @@ -73,6 +75,36 @@ static const iomux_cfg_t mx23evk_pads[] __initconst = { MX23_PAD_LCD_RESET__GPIO_1_18 | MXS_PAD_CTRL, /* backlight control */ MX23_PAD_PWM2__GPIO_1_28 | MXS_PAD_CTRL, + + /* mmc */ + MX23_PAD_SSP1_DATA0__SSP1_DATA0 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_SSP1_DATA1__SSP1_DATA1 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_SSP1_DATA2__SSP1_DATA2 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_SSP1_DATA3__SSP1_DATA3 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_GPMI_D08__SSP1_DATA4 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_GPMI_D09__SSP1_DATA5 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_GPMI_D10__SSP1_DATA6 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_GPMI_D11__SSP1_DATA7 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_SSP1_CMD__SSP1_CMD | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX23_PAD_SSP1_DETECT__SSP1_DETECT | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + MX23_PAD_SSP1_SCK__SSP1_SCK | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + /* write protect */ + MX23_PAD_PWM4__GPIO_1_30 | + (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + /* slot power enable */ + MX23_PAD_PWM3__GPIO_1_29 | + (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), }; /* mxsfb (lcdif) */ @@ -101,6 +133,11 @@ static const struct mxsfb_platform_data mx23evk_mxsfb_pdata __initconst = { .ld_intf_width = STMLCDIF_24BIT, }; +static struct mxs_mmc_platform_data mx23evk_mmc_pdata __initdata = { + .wp_gpio = MX23EVK_MMC0_WRITE_PROTECT, + .flags = SLOTF_8_BIT_CAPABLE, +}; + static void __init mx23evk_init(void) { int ret; @@ -110,6 +147,13 @@ static void __init mx23evk_init(void) mx23_add_duart(); mx23_add_auart0(); + /* power on mmc slot by writing 0 to the gpio */ + ret = gpio_request_one(MX23EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT, + "mmc0-slot-power"); + if (ret) + pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret); + mx23_add_mxs_mmc(0, &mx23evk_mmc_pdata); + ret = gpio_request_one(MX23EVK_LCD_ENABLE, GPIOF_DIR_OUT, "lcd-enable"); if (ret) pr_warn("failed to request gpio lcd-enable: %d\n", ret); diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c index 08002d02267a..bb329b9a2608 100644 --- a/arch/arm/mach-mxs/mach-mx28evk.c +++ b/arch/arm/mach-mxs/mach-mx28evk.c @@ -34,6 +34,11 @@ #define MX28EVK_LCD_ENABLE MXS_GPIO_NR(3, 30) #define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13) +#define MX28EVK_MMC0_WRITE_PROTECT MXS_GPIO_NR(2, 12) +#define MX28EVK_MMC1_WRITE_PROTECT MXS_GPIO_NR(0, 28) +#define MX28EVK_MMC0_SLOT_POWER MXS_GPIO_NR(3, 28) +#define MX28EVK_MMC1_SLOT_POWER MXS_GPIO_NR(3, 29) + static const iomux_cfg_t mx28evk_pads[] __initconst = { /* duart */ MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL, @@ -115,6 +120,65 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = { MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL, /* backlight control */ MX28_PAD_PWM2__GPIO_3_18 | MXS_PAD_CTRL, + /* mmc0 */ + MX28_PAD_SSP0_DATA0__SSP0_D0 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA1__SSP0_D1 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA2__SSP0_D2 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA3__SSP0_D3 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA4__SSP0_D4 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA5__SSP0_D5 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA6__SSP0_D6 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DATA7__SSP0_D7 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_CMD__SSP0_CMD | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + MX28_PAD_SSP0_SCK__SSP0_SCK | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + /* write protect */ + MX28_PAD_SSP1_SCK__GPIO_2_12 | + (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + /* slot power enable */ + MX28_PAD_PWM3__GPIO_3_28 | + (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + + /* mmc1 */ + MX28_PAD_GPMI_D00__SSP1_D0 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_D01__SSP1_D1 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_D02__SSP1_D2 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_D03__SSP1_D3 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_D04__SSP1_D4 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_D05__SSP1_D5 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_D06__SSP1_D6 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_D07__SSP1_D7 | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_RDY1__SSP1_CMD | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP), + MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT | + (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + MX28_PAD_GPMI_WRN__SSP1_SCK | + (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + /* write protect */ + MX28_PAD_GPMI_RESETN__GPIO_0_28 | + (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), + /* slot power enable */ + MX28_PAD_PWM4__GPIO_3_29 | + (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL), }; /* fec */ @@ -258,6 +322,18 @@ static const struct mxsfb_platform_data mx28evk_mxsfb_pdata __initconst = { .ld_intf_width = STMLCDIF_24BIT, }; +static struct mxs_mmc_platform_data mx28evk_mmc_pdata[] __initdata = { + { + /* mmc0 */ + .wp_gpio = MX28EVK_MMC0_WRITE_PROTECT, + .flags = SLOTF_8_BIT_CAPABLE, + }, { + /* mmc1 */ + .wp_gpio = MX28EVK_MMC1_WRITE_PROTECT, + .flags = SLOTF_8_BIT_CAPABLE, + }, +}; + static void __init mx28evk_init(void) { int ret; @@ -297,6 +373,19 @@ static void __init mx28evk_init(void) gpio_set_value(MX28EVK_BL_ENABLE, 1); mx28_add_mxsfb(&mx28evk_mxsfb_pdata); + + /* power on mmc slot by writing 0 to the gpio */ + ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT, + "mmc0-slot-power"); + if (ret) + pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret); + mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]); + + ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_DIR_OUT, + "mmc1-slot-power"); + if (ret) + pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret); + mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]); } static void __init mx28evk_timer_init(void) diff --git a/arch/arm/mach-mxs/module-tx28.c b/arch/arm/mach-mxs/module-tx28.c index fa0b154da67b..0fcff47009cf 100644 --- a/arch/arm/mach-mxs/module-tx28.c +++ b/arch/arm/mach-mxs/module-tx28.c @@ -45,7 +45,7 @@ static const iomux_cfg_t tx28_fec_gpio_pads[] __initconst = { }; #define FEC_MODE (MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3) -static const iomux_cfg_t tx28_fec_pads[] __initconst = { +static const iomux_cfg_t tx28_fec0_pads[] __initconst = { MX28_PAD_ENET0_MDC__ENET0_MDC | FEC_MODE, MX28_PAD_ENET0_MDIO__ENET0_MDIO | FEC_MODE, MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | FEC_MODE, @@ -57,7 +57,20 @@ static const iomux_cfg_t tx28_fec_pads[] __initconst = { MX28_PAD_ENET_CLK__CLKCTRL_ENET | FEC_MODE, }; -static const struct fec_platform_data tx28_fec_data __initconst = { +static const iomux_cfg_t tx28_fec1_pads[] __initconst = { + MX28_PAD_ENET0_RXD2__ENET1_RXD0, + MX28_PAD_ENET0_RXD3__ENET1_RXD1, + MX28_PAD_ENET0_TXD2__ENET1_TXD0, + MX28_PAD_ENET0_TXD3__ENET1_TXD1, + MX28_PAD_ENET0_COL__ENET1_TX_EN, + MX28_PAD_ENET0_CRS__ENET1_RX_EN, +}; + +static struct fec_platform_data tx28_fec0_data = { + .phy = PHY_INTERFACE_MODE_RMII, +}; + +static struct fec_platform_data tx28_fec1_data = { .phy = PHY_INTERFACE_MODE_RMII, }; @@ -108,15 +121,15 @@ int __init tx28_add_fec0(void) pr_debug("%s: Deasserting FEC PHY RESET\n", __func__); gpio_set_value(TX28_FEC_PHY_RESET, 1); - ret = mxs_iomux_setup_multiple_pads(tx28_fec_pads, - ARRAY_SIZE(tx28_fec_pads)); + ret = mxs_iomux_setup_multiple_pads(tx28_fec0_pads, + ARRAY_SIZE(tx28_fec0_pads)); if (ret) { pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n", __func__, ret); goto free_gpios; } - pr_debug("%s: Registering FEC device\n", __func__); - mx28_add_fec(0, &tx28_fec_data); + pr_debug("%s: Registering FEC0 device\n", __func__); + mx28_add_fec(0, &tx28_fec0_data); return 0; free_gpios: @@ -129,3 +142,19 @@ free_gpios: return ret; } + +int __init tx28_add_fec1(void) +{ + int ret; + + ret = mxs_iomux_setup_multiple_pads(tx28_fec1_pads, + ARRAY_SIZE(tx28_fec1_pads)); + if (ret) { + pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n", + __func__, ret); + return ret; + } + pr_debug("%s: Registering FEC1 device\n", __func__); + mx28_add_fec(1, &tx28_fec1_data); + return 0; +} diff --git a/arch/arm/mach-mxs/module-tx28.h b/arch/arm/mach-mxs/module-tx28.h index df9e1b6e81bf..8ed425457d30 100644 --- a/arch/arm/mach-mxs/module-tx28.h +++ b/arch/arm/mach-mxs/module-tx28.h @@ -7,3 +7,4 @@ * Free Software Foundation. */ int __init tx28_add_fec0(void); +int __init tx28_add_fec1(void); diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 8554707d20a9..edb1dd2d1611 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c @@ -402,7 +402,7 @@ static void ts78xx_fpga_supports(void) /* enable devices if magic matches */ switch ((ts78xx_fpga.id >> 8) & 0xffffff) { case TS7800_FPGA_MAGIC: - printk(KERN_WARNING "TS-7800 FPGA: unrecognized revision 0x%.2x\n", + pr_warning("TS-7800 FPGA: unrecognized revision 0x%.2x\n", ts78xx_fpga.id & 0xff); ts78xx_fpga.supports.ts_rtc.present = 1; ts78xx_fpga.supports.ts_nand.present = 1; @@ -423,7 +423,7 @@ static int ts78xx_fpga_load_devices(void) if (ts78xx_fpga.supports.ts_rtc.present == 1) { tmp = ts78xx_ts_rtc_load(); if (tmp) { - printk(KERN_INFO "TS-78xx: RTC not registered\n"); + pr_info("TS-78xx: RTC not registered\n"); ts78xx_fpga.supports.ts_rtc.present = 0; } ret |= tmp; @@ -431,7 +431,7 @@ static int ts78xx_fpga_load_devices(void) if (ts78xx_fpga.supports.ts_nand.present == 1) { tmp = ts78xx_ts_nand_load(); if (tmp) { - printk(KERN_INFO "TS-78xx: NAND not registered\n"); + pr_info("TS-78xx: NAND not registered\n"); ts78xx_fpga.supports.ts_nand.present = 0; } ret |= tmp; @@ -439,7 +439,7 @@ static int ts78xx_fpga_load_devices(void) if (ts78xx_fpga.supports.ts_rng.present == 1) { tmp = ts78xx_ts_rng_load(); if (tmp) { - printk(KERN_INFO "TS-78xx: RNG not registered\n"); + pr_info("TS-78xx: RNG not registered\n"); ts78xx_fpga.supports.ts_rng.present = 0; } ret |= tmp; @@ -466,7 +466,7 @@ static int ts78xx_fpga_load(void) { ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE); - printk(KERN_INFO "TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n", + pr_info("TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n", (ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff); @@ -494,7 +494,7 @@ static int ts78xx_fpga_unload(void) * UrJTAG SVN since r1381 can be used to reprogram the FPGA */ if (ts78xx_fpga.id != fpga_id) { - printk(KERN_ERR "TS-78xx FPGA: magic/rev mismatch\n" + pr_err("TS-78xx FPGA: magic/rev mismatch\n" "TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n", (ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff, (fpga_id >> 8) & 0xffffff, fpga_id & 0xff); @@ -525,7 +525,7 @@ static ssize_t ts78xx_fpga_store(struct kobject *kobj, int value, ret; if (ts78xx_fpga.state < 0) { - printk(KERN_ERR "TS-78xx FPGA: borked, you must powercycle asap\n"); + pr_err("TS-78xx FPGA: borked, you must powercycle asap\n"); return -EBUSY; } @@ -534,7 +534,7 @@ static ssize_t ts78xx_fpga_store(struct kobject *kobj, else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) value = 0; else { - printk(KERN_ERR "ts78xx_fpga_store: Invalid value\n"); + pr_err("ts78xx_fpga_store: Invalid value\n"); return -EINVAL; } @@ -616,7 +616,7 @@ static void __init ts78xx_init(void) ret = ts78xx_fpga_load(); ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr); if (ret) - printk(KERN_ERR "sysfs_create_file failed: %d\n", ret); + pr_err("sysfs_create_file failed: %d\n", ret); } MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC") diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c index 3499fada73ae..4cb069fd9af2 100644 --- a/arch/arm/mach-pxa/am200epd.c +++ b/arch/arm/mach-pxa/am200epd.c @@ -128,8 +128,8 @@ static int am200_init_gpio_regs(struct metronomefb_par *par) return 0; err_req_gpio: - while (i > 0) - gpio_free(gpios[i--]); + while (--i >= 0) + gpio_free(gpios[i]); return err; } @@ -194,7 +194,7 @@ static struct notifier_block am200_fb_notif = { }; /* this gets called as part of our init. these steps must be done now so - * that we can use set_pxa_fb_info */ + * that we can use pxa_set_fb_info */ static void __init am200_presetup_fb(void) { int fw; @@ -249,7 +249,7 @@ static void __init am200_presetup_fb(void) /* we divide since we told the LCD controller we're 16bpp */ am200_fb_info.modes->xres /= 2; - set_pxa_fb_info(&am200_fb_info); + pxa_set_fb_info(NULL, &am200_fb_info); } diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c index 993d75e66390..fa8bad235d9f 100644 --- a/arch/arm/mach-pxa/am300epd.c +++ b/arch/arm/mach-pxa/am300epd.c @@ -125,10 +125,7 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par) if (err) { dev_err(&am300_device->dev, "failed requesting " "gpio %d, err=%d\n", i, err); - while (i >= DB0_GPIO_PIN) - gpio_free(i--); - i = ARRAY_SIZE(gpios) - 1; - goto err_req_gpio; + goto err_req_gpio2; } } @@ -159,9 +156,13 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par) return 0; +err_req_gpio2: + while (--i >= DB0_GPIO_PIN) + gpio_free(i); + i = ARRAY_SIZE(gpios); err_req_gpio: - while (i > 0) - gpio_free(gpios[i--]); + while (--i >= 0) + gpio_free(gpios[i]); return err; } diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index 38dea05df7f8..bfbecec6d05f 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c @@ -263,7 +263,7 @@ static void __init balloon3_lcd_init(void) } balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power; - set_pxa_fb_info(&balloon3_lcd_screen); + pxa_set_fb_info(NULL, &balloon3_lcd_screen); return; err2: diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c index b734d8468168..8225e2e58c6e 100644 --- a/arch/arm/mach-pxa/cm-x2xx.c +++ b/arch/arm/mach-pxa/cm-x2xx.c @@ -379,7 +379,7 @@ __setup("monitor=", cmx2xx_set_display); static void __init cmx2xx_init_display(void) { - set_pxa_fb_info(cmx2xx_display); + pxa_set_fb_info(NULL, cmx2xx_display); } #else static inline void cmx2xx_init_display(void) {} diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 06d0a03f462d..b2248e76ec8b 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -296,7 +296,7 @@ static struct pxafb_mach_info cm_x300_lcd = { static void __init cm_x300_init_lcd(void) { - set_pxa_fb_info(&cm_x300_lcd); + pxa_set_fb_info(NULL, &cm_x300_lcd); } #else static inline void cm_x300_init_lcd(void) {} diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c index ee797397dc5b..44c1b77ece67 100644 --- a/arch/arm/mach-pxa/colibri-pxa270-income.c +++ b/arch/arm/mach-pxa/colibri-pxa270-income.c @@ -175,7 +175,7 @@ static struct pxafb_mach_info income_lcd_screen = { static void __init income_lcd_init(void) { - set_pxa_fb_info(&income_lcd_screen); + pxa_set_fb_info(NULL, &income_lcd_screen); } #else static inline void income_lcd_init(void) {} diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index 96b2d9fbfef0..3f9be419959d 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -105,7 +105,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin) lcd_bl_pin = bl_pin; gpio_request(bl_pin, "lcd backlight"); gpio_direction_output(bl_pin, 0); - set_pxa_fb_info(&sharp_lq43_info); + pxa_set_fb_info(NULL, &sharp_lq43_info); } #endif diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index d4e705caefea..3a5507e31919 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -462,7 +462,6 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = { * USB Device Controller */ static struct pxa2xx_udc_mach_info udc_info __initdata = { - .gpio_vbus = -1, /* no connect GPIO; corgi can't tell connection status */ .gpio_pullup = CORGI_GPIO_USB_PULLUP, }; diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index c4bf08b3eb61..2e0425404de5 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -90,7 +90,6 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info) static struct pxa2xx_udc_mach_info pxa_udc_info = { .gpio_pullup = -1, - .gpio_vbus = -1, }; void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) @@ -188,16 +187,12 @@ struct platform_device pxa_device_fb = { .resource = pxafb_resources, }; -void __init set_pxa_fb_info(struct pxafb_mach_info *info) +void __init pxa_set_fb_info(struct device *parent, struct pxafb_mach_info *info) { + pxa_device_fb.dev.parent = parent; pxa_register_device(&pxa_device_fb, info); } -void __init set_pxa_fb_parent(struct device *parent_dev) -{ - pxa_device_fb.dev.parent = parent_dev; -} - static struct resource pxa_resource_ffuart[] = { { .start = 0x40100000, diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index b411d7cbf5a1..f8a6e9d79a3a 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -689,7 +689,7 @@ static struct pxafb_mach_info em_x270_lcd = { static void __init em_x270_init_lcd(void) { - set_pxa_fb_info(&em_x270_lcd); + pxa_set_fb_info(NULL, &em_x270_lcd); } #else static inline void em_x270_init_lcd(void) {} diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index edca0a043293..2e3970fdde0b 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -20,6 +20,7 @@ #include <linux/mfd/t7l66xb.h> #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/usb/gpio_vbus.h> #include <video/w100fb.h> @@ -51,12 +52,20 @@ void __init eseries_fixup(struct machine_desc *desc, mi->bank[0].size = (64*1024*1024); } -struct pxa2xx_udc_mach_info e7xx_udc_mach_info = { +struct gpio_vbus_mach_info e7xx_udc_info = { .gpio_vbus = GPIO_E7XX_USB_DISC, .gpio_pullup = GPIO_E7XX_USB_PULLUP, .gpio_pullup_inverted = 1 }; +static struct platform_device e7xx_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &e7xx_udc_info, + }, +}; + struct pxaficp_platform_data e7xx_ficp_platform_data = { .gpio_pwdown = GPIO_E7XX_IR_OFF, .transceiver_cap = IR_SIRMODE | IR_OFF, @@ -165,6 +174,7 @@ static struct platform_device e330_tc6387xb_device = { static struct platform_device *e330_devices[] __initdata = { &e330_tc6387xb_device, + &e7xx_gpio_vbus, }; static void __init e330_init(void) @@ -175,7 +185,6 @@ static void __init e330_init(void) eseries_register_clks(); eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e330_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); } MACHINE_START(E330, "Toshiba e330") @@ -214,6 +223,7 @@ static struct platform_device e350_t7l66xb_device = { static struct platform_device *e350_devices[] __initdata = { &e350_t7l66xb_device, + &e7xx_gpio_vbus, }; static void __init e350_init(void) @@ -224,7 +234,6 @@ static void __init e350_init(void) eseries_register_clks(); eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e350_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); } MACHINE_START(E350, "Toshiba e350") @@ -333,6 +342,7 @@ static struct platform_device e400_t7l66xb_device = { static struct platform_device *e400_devices[] __initdata = { &e400_t7l66xb_device, + &e7xx_gpio_vbus, }; static void __init e400_init(void) @@ -344,9 +354,8 @@ static void __init e400_init(void) /* Fixme - e400 may have a switched clock */ eseries_register_clks(); eseries_get_tmio_gpios(); - set_pxa_fb_info(&e400_pxafb_mach_info); + pxa_set_fb_info(NULL, &e400_pxafb_mach_info); platform_add_devices(ARRAY_AND_SIZE(e400_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); } MACHINE_START(E400, "Toshiba e400") @@ -519,6 +528,7 @@ static struct platform_device e740_t7l66xb_device = { static struct platform_device *e740_devices[] __initdata = { &e740_fb_device, &e740_t7l66xb_device, + &e7xx_gpio_vbus, }; static void __init e740_init(void) @@ -532,7 +542,6 @@ static void __init e740_init(void) "UDCCLK", &pxa25x_device_udc.dev), eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e740_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_ac97_info(NULL); pxa_set_ficp_info(&e7xx_ficp_platform_data); } @@ -711,6 +720,7 @@ static struct platform_device e750_tc6393xb_device = { static struct platform_device *e750_devices[] __initdata = { &e750_fb_device, &e750_tc6393xb_device, + &e7xx_gpio_vbus, }; static void __init e750_init(void) @@ -723,7 +733,6 @@ static void __init e750_init(void) "GPIO11_CLK", NULL), eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e750_devices)); - pxa_set_udc_info(&e7xx_udc_mach_info); pxa_set_ac97_info(NULL); pxa_set_ficp_info(&e7xx_ficp_platform_data); } @@ -873,12 +882,21 @@ static struct platform_device e800_fb_device = { /* --------------------------- UDC definitions --------------------------- */ -static struct pxa2xx_udc_mach_info e800_udc_mach_info = { +static struct gpio_vbus_mach_info e800_udc_info = { .gpio_vbus = GPIO_E800_USB_DISC, .gpio_pullup = GPIO_E800_USB_PULLUP, .gpio_pullup_inverted = 1 }; +static struct platform_device e800_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &e800_udc_info, + }, +}; + + /* ----------------- e800 tc6393xb parameters ------------------ */ static struct tc6393xb_platform_data e800_tc6393xb_info = { @@ -907,6 +925,7 @@ static struct platform_device e800_tc6393xb_device = { static struct platform_device *e800_devices[] __initdata = { &e800_fb_device, &e800_tc6393xb_device, + &e800_gpio_vbus, }; static void __init e800_init(void) @@ -919,7 +938,6 @@ static void __init e800_init(void) "GPIO11_CLK", NULL), eseries_get_tmio_gpios(); platform_add_devices(ARRAY_AND_SIZE(e800_devices)); - pxa_set_udc_info(&e800_udc_mach_info); pxa_set_ac97_info(NULL); } diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c index 93f05e024313..d88aed8fbe15 100644 --- a/arch/arm/mach-pxa/ezx.c +++ b/arch/arm/mach-pxa/ezx.c @@ -783,7 +783,7 @@ static void __init a780_init(void) pxa_set_i2c_info(NULL); - set_pxa_fb_info(&ezx_fb_info_1); + pxa_set_fb_info(NULL, &ezx_fb_info_1); pxa_set_keypad_info(&a780_keypad_platform_data); @@ -853,7 +853,7 @@ static void __init e680_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_1); + pxa_set_fb_info(NULL, &ezx_fb_info_1); pxa_set_keypad_info(&e680_keypad_platform_data); @@ -918,7 +918,7 @@ static void __init a1200_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_2); + pxa_set_fb_info(NULL, &ezx_fb_info_2); pxa_set_keypad_info(&a1200_keypad_platform_data); @@ -1103,7 +1103,7 @@ static void __init a910_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_2); + pxa_set_fb_info(NULL, &ezx_fb_info_2); pxa_set_keypad_info(&a910_keypad_platform_data); @@ -1173,7 +1173,7 @@ static void __init e6_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_2); + pxa_set_fb_info(NULL, &ezx_fb_info_2); pxa_set_keypad_info(&e6_keypad_platform_data); @@ -1212,7 +1212,7 @@ static void __init e2_init(void) pxa_set_i2c_info(NULL); i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info)); - set_pxa_fb_info(&ezx_fb_info_2); + pxa_set_fb_info(NULL, &ezx_fb_info_2); pxa_set_keypad_info(&e2_keypad_platform_data); diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index 6fd319ea5284..d65e4bde9b91 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -26,6 +26,7 @@ #include <linux/gpio.h> #include <linux/err.h> #include <linux/clk.h> +#include <linux/usb/gpio_vbus.h> #include <asm/setup.h> #include <asm/memory.h> @@ -106,14 +107,22 @@ static void __init gumstix_mmc_init(void) #endif #ifdef CONFIG_USB_GADGET_PXA25X -static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = { +static struct gpio_vbus_mach_info gumstix_udc_info = { .gpio_vbus = GPIO_GUMSTIX_USB_GPIOn, .gpio_pullup = GPIO_GUMSTIX_USB_GPIOx, }; +static struct platform_device gumstix_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &gumstix_udc_info, + }, +}; + static void __init gumstix_udc_init(void) { - pxa_set_udc_info(&gumstix_udc_info); + platform_device_register(&gumstix_gpio_vbus); } #else static void gumstix_udc_init(void) diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index dd40e4a9291c..f7fb64f11a7d 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -167,7 +167,7 @@ static void __init idp_init(void) platform_device_register(&smc91x_device); //platform_device_register(&mst_audio_device); - set_pxa_fb_info(&sharp_lm8v31); + pxa_set_fb_info(NULL, &sharp_lm8v31); pxa_set_mci_info(&idp_mci_platform_data); } diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h index 2bbcf70dd935..0d4700a79612 100644 --- a/arch/arm/mach-pxa/include/mach/palmz72.h +++ b/arch/arm/mach-pxa/include/mach/palmz72.h @@ -44,6 +44,11 @@ #define GPIO_NR_PALMZ72_BT_POWER 17 #define GPIO_NR_PALMZ72_BT_RESET 83 +/* Camera */ +#define GPIO_NR_PALMZ72_CAM_PWDN 56 +#define GPIO_NR_PALMZ72_CAM_RESET 57 +#define GPIO_NR_PALMZ72_CAM_POWER 91 + /** Initial values **/ /* Battery */ diff --git a/arch/arm/mach-pxa/include/mach/pxafb.h b/arch/arm/mach-pxa/include/mach/pxafb.h index 160ec83f51a6..01a45ac48114 100644 --- a/arch/arm/mach-pxa/include/mach/pxafb.h +++ b/arch/arm/mach-pxa/include/mach/pxafb.h @@ -154,8 +154,8 @@ struct pxafb_mach_info { void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *); void (*smart_update)(struct fb_info *); }; -void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info); -void set_pxa_fb_parent(struct device *parent_dev); + +void pxa_set_fb_info(struct device *, struct pxafb_mach_info *); unsigned long pxafb_get_hsync_time(struct device *dev); extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int); diff --git a/arch/arm/mach-pxa/include/mach/z2.h b/arch/arm/mach-pxa/include/mach/z2.h index 8835c16bc82f..7b0f71ef3167 100644 --- a/arch/arm/mach-pxa/include/mach/z2.h +++ b/arch/arm/mach-pxa/include/mach/z2.h @@ -25,8 +25,7 @@ #define GPIO98_ZIPITZ2_LID_BUTTON 98 /* Libertas GSPI8686 WiFi */ -#define GPIO14_ZIPITZ2_WIFI_RESET 14 -#define GPIO15_ZIPITZ2_WIFI_POWER 15 +#define GPIO14_ZIPITZ2_WIFI_POWER 14 #define GPIO24_ZIPITZ2_WIFI_CS 24 #define GPIO36_ZIPITZ2_WIFI_IRQ 36 diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 87c1ed9ccd2f..e5e326d2cdc9 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -185,7 +185,7 @@ static struct pxafb_mach_info littleton_lcd_info = { static void littleton_init_lcd(void) { - set_pxa_fb_info(&littleton_lcd_info); + pxa_set_fb_info(NULL, &littleton_lcd_info); } #else static inline void littleton_init_lcd(void) {}; diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 6307f70ae22a..f5de541725b1 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -480,7 +480,7 @@ static void __init lpd270_init(void) pxa_set_ac97_info(NULL); if (lpd270_lcd_to_use != NULL) - set_pxa_fb_info(lpd270_lcd_to_use); + pxa_set_fb_info(NULL, lpd270_lcd_to_use); pxa_set_ohci_info(&lpd270_ohci_platform_data); } diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 0fea945dd6f2..3ede978c83d9 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -521,7 +521,7 @@ static void __init lubbock_init(void) clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL); pxa_set_udc_info(&udc_info); - set_pxa_fb_info(&sharp_lm8v31); + pxa_set_fb_info(NULL, &sharp_lm8v31); pxa_set_mci_info(&lubbock_mci_platform_data); pxa_set_ficp_info(&lubbock_ficp_platform_data); pxa_set_ac97_info(NULL); diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index 5535991c4a3c..a72993dde2b3 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -757,7 +757,7 @@ static void __init magician_init(void) gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0); gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0); gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0); - set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info); + pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info); } else pr_err("LCD detection: CPLD mapping failed\n"); } diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 29b6e7a94e11..95163baca29e 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -592,7 +592,7 @@ static void __init mainstone_init(void) else mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode; - set_pxa_fb_info(&mainstone_pxafb_info); + pxa_set_fb_info(NULL, &mainstone_pxafb_info); mainstone_backlight_register(); pxa_set_mci_info(&mainstone_mci_platform_data); diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 78d98a8607ec..dd13bb63259b 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -795,7 +795,7 @@ static void __init mioa701_machine_init(void) pxa_set_stuart_info(NULL); mio_gpio_request(ARRAY_AND_SIZE(global_gpios)); bootstrap_init(); - set_pxa_fb_info(&mioa701_pxafb_info); + pxa_set_fb_info(NULL, &mioa701_pxafb_info); pxa_set_mci_info(&mioa701_mci_info); pxa_set_keypad_info(&mioa701_keypad_info); pxa_set_udc_info(&mioa701_udc_info); diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 72adb3ae2b43..325c245c0a0d 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c @@ -1,8 +1,7 @@ /* * Common code for Palm LD, T5, TX, Z72 * - * Copyright (C) 2010 - * Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -158,7 +157,7 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode) palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl; } - set_pxa_fb_info(&palm27x_lcd_screen); + pxa_set_fb_info(NULL, &palm27x_lcd_screen); } #endif diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index a09a2374697b..fb06bd047272 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -507,7 +507,7 @@ static struct pxafb_mach_info palmtc_lcd_screen = { static void __init palmtc_lcd_init(void) { - set_pxa_fb_info(&palmtc_lcd_screen); + pxa_set_fb_info(NULL, &palmtc_lcd_screen); } #else static inline void palmtc_lcd_init(void) {} diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 3f25014a136c..726f5b98dcd3 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -136,30 +136,14 @@ static struct platform_device palmte2_pxa_keys = { /****************************************************************************** * Backlight ******************************************************************************/ +static struct gpio palmte_bl_gpios[] = { + { GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" }, + { GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" }, +}; + static int palmte2_backlight_init(struct device *dev) { - int ret; - - ret = gpio_request(GPIO_NR_PALMTE2_BL_POWER, "BL POWER"); - if (ret) - goto err; - ret = gpio_direction_output(GPIO_NR_PALMTE2_BL_POWER, 0); - if (ret) - goto err2; - ret = gpio_request(GPIO_NR_PALMTE2_LCD_POWER, "LCD POWER"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMTE2_LCD_POWER, 0); - if (ret) - goto err3; - - return 0; -err3: - gpio_free(GPIO_NR_PALMTE2_LCD_POWER); -err2: - gpio_free(GPIO_NR_PALMTE2_BL_POWER); -err: - return ret; + return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios)); } static int palmte2_backlight_notify(struct device *dev, int brightness) @@ -171,8 +155,7 @@ static int palmte2_backlight_notify(struct device *dev, int brightness) static void palmte2_backlight_exit(struct device *dev) { - gpio_free(GPIO_NR_PALMTE2_BL_POWER); - gpio_free(GPIO_NR_PALMTE2_LCD_POWER); + gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios)); } static struct platform_pwm_backlight_data palmte2_backlight_data = { @@ -363,7 +346,7 @@ static void __init palmte2_init(void) pxa_set_btuart_info(NULL); pxa_set_stuart_info(NULL); - set_pxa_fb_info(&palmte2_lcd_screen); + pxa_set_fb_info(NULL, &palmte2_lcd_screen); pxa_set_mci_info(&palmte2_mci_platform_data); palmte2_udc_init(); pxa_set_ac97_info(&palmte2_ac97_pdata); diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index 3010193b081e..3b8a4f37dbbe 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -30,6 +30,7 @@ #include <linux/wm97xx.h> #include <linux/power_supply.h> #include <linux/usb/gpio_vbus.h> +#include <linux/i2c-gpio.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -47,6 +48,9 @@ #include <mach/palm27x.h> #include <mach/pm.h> +#include <mach/camera.h> + +#include <media/soc_camera.h> #include "generic.h" #include "devices.h" @@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = { GPIO22_GPIO, /* LCD border color */ GPIO96_GPIO, /* lcd power */ + /* PXA Camera */ + GPIO81_CIF_DD_0, + GPIO48_CIF_DD_5, + GPIO50_CIF_DD_3, + GPIO51_CIF_DD_2, + GPIO52_CIF_DD_4, + GPIO53_CIF_MCLK, + GPIO54_CIF_PCLK, + GPIO55_CIF_DD_1, + GPIO84_CIF_FV, + GPIO85_CIF_LV, + GPIO93_CIF_DD_6, + GPIO108_CIF_DD_7, + + GPIO56_GPIO, /* OV9640 Powerdown */ + GPIO57_GPIO, /* OV9640 Reset */ + GPIO91_GPIO, /* OV9640 Power */ + + /* I2C */ + GPIO117_GPIO, /* I2C_SCL */ + GPIO118_GPIO, /* I2C_SDA */ + /* Misc. */ GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* power detect */ GPIO88_GPIO, /* green led */ @@ -254,6 +280,106 @@ device_initcall(palmz72_pm_init); #endif /****************************************************************************** + * SoC Camera + ******************************************************************************/ +#if defined(CONFIG_SOC_CAMERA_OV9640) || \ + defined(CONFIG_SOC_CAMERA_OV9640_MODULE) +static struct pxacamera_platform_data palmz72_pxacamera_platform_data = { + .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 | + PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN, + .mclk_10khz = 2600, +}; + +/* Board I2C devices. */ +static struct i2c_board_info palmz72_i2c_device[] = { + { + I2C_BOARD_INFO("ov9640", 0x30), + } +}; + +static int palmz72_camera_power(struct device *dev, int power) +{ + gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power); + mdelay(50); + return 0; +} + +static int palmz72_camera_reset(struct device *dev) +{ + gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1); + mdelay(50); + gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0); + mdelay(50); + return 0; +} + +static struct soc_camera_link palmz72_iclink = { + .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */ + .board_info = &palmz72_i2c_device[0], + .i2c_adapter_id = 0, + .module_name = "ov96xx", + .power = &palmz72_camera_power, + .reset = &palmz72_camera_reset, + .flags = SOCAM_DATAWIDTH_8, +}; + +static struct i2c_gpio_platform_data palmz72_i2c_bus_data = { + .sda_pin = 118, + .scl_pin = 117, + .udelay = 10, + .timeout = 100, +}; + +static struct platform_device palmz72_i2c_bus_device = { + .name = "i2c-gpio", + .id = 0, /* we use this as a replacement for i2c-pxa */ + .dev = { + .platform_data = &palmz72_i2c_bus_data, + } +}; + +static struct platform_device palmz72_camera = { + .name = "soc-camera-pdrv", + .id = -1, + .dev = { + .platform_data = &palmz72_iclink, + }, +}; + +/* Here we request the camera GPIOs and configure them. We power up the camera + * module, deassert the reset pin, but put it into powerdown (low to no power + * consumption) mode. This allows us to later bring the module up fast. */ +static struct gpio palmz72_camera_gpios[] = { + { GPIO_NR_PALMZ72_CAM_POWER, GPIOF_INIT_HIGH,"Camera DVDD" }, + { GPIO_NR_PALMZ72_CAM_RESET, GPIOF_INIT_LOW, "Camera RESET" }, + { GPIO_NR_PALMZ72_CAM_PWDN, GPIOF_INIT_LOW, "Camera PWDN" }, +}; + +static inline void __init palmz72_cam_gpio_init(void) +{ + int ret; + + ret = gpio_request_array(ARRAY_AND_SIZE(palmz72_camera_gpios)); + if (!ret) + gpio_free_array(ARRAY_AND_SIZE(palmz72_camera_gpios)); + else + printk(KERN_ERR "Camera GPIO init failed!\n"); + + return; +} + +static void __init palmz72_camera_init(void) +{ + palmz72_cam_gpio_init(); + pxa_set_camera_info(&palmz72_pxacamera_platform_data); + platform_device_register(&palmz72_i2c_bus_device); + platform_device_register(&palmz72_camera); +} +#else +static inline void palmz72_camera_init(void) {} +#endif + +/****************************************************************************** * Machine init ******************************************************************************/ static void __init palmz72_init(void) @@ -276,6 +402,7 @@ static void __init palmz72_init(void) palm27x_pmic_init(); palmz72_kpc_init(); palmz72_leds_init(); + palmz72_camera_init(); } MACHINE_START(PALMZ72, "Palm Zire72") diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 4d0120540124..6d5b7e062124 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -515,7 +515,7 @@ void __init pcm990_baseboard_init(void) pcm990_init_irq(); #ifndef CONFIG_PCM990_DISPLAY_NONE - set_pxa_fb_info(&pcm990_fbinfo); + pxa_set_fb_info(NULL, &pcm990_fbinfo); #endif platform_device_register(&pcm990_backlight_device); diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 35353af345d5..16d14fd79b4b 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -445,8 +445,7 @@ static void __init poodle_init(void) if (ret) pr_warning("poodle: Unable to register LoCoMo device\n"); - set_pxa_fb_parent(&poodle_locomo_device.dev); - set_pxa_fb_info(&poodle_fb_info); + pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info); pxa_set_udc_info(&udc_info); pxa_set_mci_info(&poodle_mci_platform_data); pxa_set_ficp_info(&poodle_ficp_platform_data); diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 47094188e029..cd1861351f75 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -597,7 +597,7 @@ static void __init raumfeld_lcd_init(void) { int ret; - set_pxa_fb_info(&raumfeld_sharp_lcd_info); + pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info); /* Earlier devices had the backlight regulator controlled * via PWM, later versions use another controller for that */ diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index eb83c89428ef..fee97a935122 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -473,7 +473,7 @@ static struct pxafb_mach_info saar_lcd_info = { static void __init saar_init_lcd(void) { - set_pxa_fb_info(&saar_lcd_info); + pxa_set_fb_info(NULL, &saar_lcd_info); } #else static inline void saar_init_lcd(void) {} diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 38e2c0912b9a..01c576963e94 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -724,7 +724,7 @@ static struct pxafb_mach_info spitz_pxafb_info = { static void __init spitz_lcd_init(void) { - set_pxa_fb_info(&spitz_pxafb_info); + pxa_set_fb_info(NULL, &spitz_pxafb_info); } #else static inline void spitz_lcd_init(void) {} diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 9cecf8366db8..53d4a472b699 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -466,7 +466,7 @@ static void __init tavorevb_init_lcd(void) { platform_device_register(&tavorevb_backlight_devices[0]); platform_device_register(&tavorevb_backlight_devices[1]); - set_pxa_fb_info(&tavorevb_lcd_info); + pxa_set_fb_info(NULL, &tavorevb_lcd_info); } #else static inline void tavorevb_init_lcd(void) {} diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index e7f64d9b4f2d..428da3ff33a5 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -100,7 +100,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev) static struct clock_event_device ckevt_pxa_osmr0 = { .name = "osmr0", .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, .rating = 200, .set_next_event = pxa_osmr0_set_next_event, .set_mode = pxa_osmr0_set_mode, @@ -135,8 +134,8 @@ static void __init pxa_timer_init(void) init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate); - ckevt_pxa_osmr0.mult = - div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift); + clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4); + clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4); ckevt_pxa_osmr0.max_delta_ns = clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0); ckevt_pxa_osmr0.min_delta_ns = diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 5ad3807af334..5fa145778e7d 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -35,6 +35,7 @@ #include <linux/spi/pxa2xx_spi.h> #include <linux/input/matrix_keypad.h> #include <linux/i2c/pxa-i2c.h> +#include <linux/usb/gpio_vbus.h> #include <asm/setup.h> #include <asm/mach-types.h> @@ -240,12 +241,20 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = { /* * USB Device Controller */ -static struct pxa2xx_udc_mach_info udc_info __initdata = { +static struct gpio_vbus_mach_info tosa_udc_info = { .gpio_pullup = TOSA_GPIO_USB_PULLUP, .gpio_vbus = TOSA_GPIO_USB_IN, .gpio_vbus_inverted = 1, }; +static struct platform_device tosa_gpio_vbus = { + .name = "gpio-vbus", + .id = -1, + .dev = { + .platform_data = &tosa_udc_info, + }, +}; + /* * MMC/SD Device */ @@ -891,6 +900,7 @@ static struct platform_device *devices[] __initdata = { &tosa_bt_device, &sharpsl_rom_device, &wm9712_device, + &tosa_gpio_vbus, }; static void tosa_poweroff(void) @@ -937,7 +947,6 @@ static void __init tosa_init(void) dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16); pxa_set_mci_info(&tosa_mci_platform_data); - pxa_set_udc_info(&udc_info); pxa_set_ficp_info(&tosa_ficp_platform_data); pxa_set_i2c_info(NULL); pxa_set_ac97_info(NULL); diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 857bb2e63486..b9cfbebdfe9c 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -516,9 +516,9 @@ static void __init trizeps4_init(void) pxa_set_stuart_info(NULL); if (0) /* dont know how to determine LCD */ - set_pxa_fb_info(&sharp_lcd); + pxa_set_fb_info(NULL, &sharp_lcd); else - set_pxa_fb_info(&toshiba_lcd); + pxa_set_fb_info(NULL, &toshiba_lcd); pxa_set_mci_info(&trizeps4_mci_platform_data); #ifndef STATUS_LEDS_ON_STUART_PINS diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index aa70331c0805..b523f119e0f0 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -932,7 +932,7 @@ static void __init viper_init(void) /* Wake-up serial console */ viper_init_serial_gpio(); - set_pxa_fb_info(&fb_info); + pxa_set_fb_info(NULL, &fb_info); /* v1 hardware cannot use the datacs line */ version = viper_hw_version(); diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index e709fd459268..f71d377c8640 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -572,7 +572,7 @@ static void __init vpac270_lcd_init(void) } vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power; - set_pxa_fb_info(&vpac270_lcd_screen); + pxa_set_fb_info(NULL, &vpac270_lcd_screen); return; err2: diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index aaf883754ef4..fbe9e02e2f9f 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -91,13 +91,13 @@ static unsigned long z2_pin_config[] = { GPIO47_STUART_TXD, /* Keypad */ - GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH, - GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH, - GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH, - GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH, - GPIO38_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH, - GPIO16_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH, - GPIO17_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH, + GPIO100_KP_MKIN_0, + GPIO101_KP_MKIN_1, + GPIO102_KP_MKIN_2, + GPIO34_KP_MKIN_3, + GPIO38_KP_MKIN_4, + GPIO16_KP_MKIN_5, + GPIO17_KP_MKIN_6, GPIO103_KP_MKOUT_0, GPIO104_KP_MKOUT_1, GPIO105_KP_MKOUT_2, @@ -138,8 +138,7 @@ static unsigned long z2_pin_config[] = { GPIO1_GPIO, /* Power button */ GPIO37_GPIO, /* Headphone detect */ GPIO98_GPIO, /* Lid switch */ - GPIO14_GPIO, /* WiFi Reset */ - GPIO15_GPIO, /* WiFi Power */ + GPIO14_GPIO, /* WiFi Power */ GPIO24_GPIO, /* WiFi CS */ GPIO36_GPIO, /* WiFi IRQ */ GPIO88_GPIO, /* LCD CS */ @@ -204,7 +203,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = { /* Keypad Backlight */ .pwm_id = 1, .max_brightness = 1023, - .dft_brightness = 512, + .dft_brightness = 0, .pwm_period_ns = 1260320, }, [1] = { @@ -271,7 +270,7 @@ static struct pxafb_mach_info z2_lcd_screen = { static void __init z2_lcd_init(void) { - set_pxa_fb_info(&z2_lcd_screen); + pxa_set_fb_info(NULL, &z2_lcd_screen); } #else static inline void z2_lcd_init(void) {} @@ -309,12 +308,12 @@ struct gpio_led z2_gpio_leds[] = { .active_low = 1, }, { .name = "z2:green:charged", - .default_trigger = "none", + .default_trigger = "mmc0", .gpio = GPIO85_ZIPITZ2_LED_CHARGED, .active_low = 1, }, { .name = "z2:amber:charging", - .default_trigger = "none", + .default_trigger = "Z2-charging-or-full", .gpio = GPIO83_ZIPITZ2_LED_CHARGING, .active_low = 1, }, @@ -427,8 +426,22 @@ static inline void z2_mkp_init(void) {} ******************************************************************************/ #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) static struct gpio_keys_button z2_pxa_buttons[] = { - {KEY_POWER, GPIO1_ZIPITZ2_POWER_BUTTON, 0, "Power Button" }, - {KEY_CLOSE, GPIO98_ZIPITZ2_LID_BUTTON, 0, "Lid Button" }, + { + .code = KEY_POWER, + .gpio = GPIO1_ZIPITZ2_POWER_BUTTON, + .active_low = 0, + .desc = "Power Button", + .wakeup = 1, + .type = EV_KEY, + }, + { + .code = SW_LID, + .gpio = GPIO98_ZIPITZ2_LID_BUTTON, + .active_low = 1, + .desc = "Lid Switch", + .wakeup = 0, + .type = EV_SW, + }, }; static struct gpio_keys_platform_data z2_pxa_keys_data = { @@ -461,9 +474,9 @@ static struct z2_battery_info batt_chip_info = { .batt_I2C_addr = 0x55, .batt_I2C_reg = 2, .charge_gpio = GPIO0_ZIPITZ2_AC_DETECT, - .min_voltage = 2400000, - .max_voltage = 3700000, - .batt_div = 69, + .min_voltage = 3475000, + .max_voltage = 4190000, + .batt_div = 59, .batt_mult = 1000000, .batt_tech = POWER_SUPPLY_TECHNOLOGY_LION, .batt_name = "Z2", @@ -497,26 +510,16 @@ static int z2_lbs_spi_setup(struct spi_device *spi) { int ret = 0; - ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power"); + ret = gpio_request(GPIO14_ZIPITZ2_WIFI_POWER, "WiFi Power"); if (ret) goto err; - ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1); + ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_POWER, 1); if (ret) goto err2; - ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset"); - if (ret) - goto err2; - - ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0); - if (ret) - goto err3; - - /* Reset the card */ + /* Wait until card is powered on */ mdelay(180); - gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1); - mdelay(20); spi->bits_per_word = 16; spi->mode = SPI_MODE_2, @@ -525,22 +528,18 @@ static int z2_lbs_spi_setup(struct spi_device *spi) return 0; -err3: - gpio_free(GPIO14_ZIPITZ2_WIFI_RESET); err2: - gpio_free(GPIO15_ZIPITZ2_WIFI_POWER); + gpio_free(GPIO14_ZIPITZ2_WIFI_POWER); err: return ret; }; static int z2_lbs_spi_teardown(struct spi_device *spi) { - gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0); - gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0); - gpio_free(GPIO14_ZIPITZ2_WIFI_RESET); - gpio_free(GPIO15_ZIPITZ2_WIFI_POWER); - return 0; + gpio_set_value(GPIO14_ZIPITZ2_WIFI_POWER, 0); + gpio_free(GPIO14_ZIPITZ2_WIFI_POWER); + return 0; }; static struct pxa2xx_spi_chip z2_lbs_chip_info = { diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 139aa7f2ed90..00363c7ac182 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -847,7 +847,7 @@ static void __init zeus_init(void) if (zeus_setup_fb_gpios()) pr_err("Failed to setup fb gpios\n"); else - set_pxa_fb_info(&zeus_fb_info); + pxa_set_fb_info(NULL, &zeus_fb_info); pxa_set_mci_info(&zeus_mci_platform_data); pxa_set_udc_info(&zeus_udc_info); diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index a4c784aab764..5821185f77ab 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -208,7 +208,7 @@ static void __init zylonite_init_lcd(void) platform_device_register(&zylonite_backlight_device); if (lcd_id & 0x20) { - set_pxa_fb_info(&zylonite_sharp_lcd_info); + pxa_set_fb_info(NULL, &zylonite_sharp_lcd_info); return; } @@ -220,7 +220,7 @@ static void __init zylonite_init_lcd(void) else zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode; - set_pxa_fb_info(&zylonite_toshiba_lcd_info); + pxa_set_fb_info(NULL, &zylonite_toshiba_lcd_info); } #else static inline void zylonite_init_lcd(void) {} diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 2ecc1d94284e..10e75faba4c9 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -348,7 +348,7 @@ static void __init gic_init_irq(void) #ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB /* board GIC, secondary */ - gic_init(1, 64, __io_address(REALVIEW_EB_GIC_DIST_BASE), + gic_init(1, 96, __io_address(REALVIEW_EB_GIC_DIST_BASE), __io_address(REALVIEW_EB_GIC_CPU_BASE)); gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1); #endif diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 96e59e3ee4f5..eb7ffa0ee8b5 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -314,7 +314,7 @@ static struct mmci_platform_data mmc0_plat_data = { .gpio_cd = -1, }; -static struct resource chalcd_resources[] = { +static struct resource char_lcd_resources[] = { { .start = VERSATILE_CHAR_LCD_BASE, .end = (VERSATILE_CHAR_LCD_BASE + SZ_4K - 1), diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c index 6561c9df5f0d..ccc789e21daa 100644 --- a/arch/arm/plat-mxc/devices/platform-fec.c +++ b/arch/arm/plat-mxc/devices/platform-fec.c @@ -53,7 +53,7 @@ struct platform_device *__init imx_add_fec( struct resource res[] = { { .start = data->iobase, - .end = data->iobase + SZ_4K, + .end = data->iobase + SZ_4K - 1, .flags = IORESOURCE_MEM, }, { .start = data->irq, diff --git a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c index 10653cc8d1fa..805336fdc252 100644 --- a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c +++ b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c @@ -27,7 +27,7 @@ struct platform_device *__init imx_add_imxdi_rtc( struct resource res[] = { { .start = data->iobase, - .end = data->iobase + SZ_16K, + .end = data->iobase + SZ_16K - 1, .flags = IORESOURCE_MEM, }, { .start = data->irq, diff --git a/arch/arm/plat-mxc/include/mach/audmux.h b/arch/arm/plat-mxc/include/mach/audmux.h index 5cd6466964af..6fda788ed0e9 100644 --- a/arch/arm/plat-mxc/include/mach/audmux.h +++ b/arch/arm/plat-mxc/include/mach/audmux.h @@ -15,6 +15,14 @@ #define MX31_AUDMUX_PORT5_SSI_PINS_5 4 #define MX31_AUDMUX_PORT6_SSI_PINS_6 5 +#define MX51_AUDMUX_PORT1_SSI0 0 +#define MX51_AUDMUX_PORT2_SSI1 1 +#define MX51_AUDMUX_PORT3 2 +#define MX51_AUDMUX_PORT4 3 +#define MX51_AUDMUX_PORT5 4 +#define MX51_AUDMUX_PORT6 5 +#define MX51_AUDMUX_PORT7 6 + /* Register definitions for the i.MX21/27 Digital Audio Multiplexer */ #define MXC_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff) #define MXC_AUDMUX_V1_PCR_INMEN (1 << 8) @@ -28,7 +36,7 @@ #define MXC_AUDMUX_V1_PCR_TCLKDIR (1 << 30) #define MXC_AUDMUX_V1_PCR_TFSDIR (1 << 31) -/* Register definitions for the i.MX25/31/35 Digital Audio Multiplexer */ +/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */ #define MXC_AUDMUX_V2_PTCR_TFSDIR (1 << 31) #define MXC_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27) #define MXC_AUDMUX_V2_PTCR_TCLKDIR (1 << 26) diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h index c4f116d214f2..7a9b20abda09 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h @@ -90,12 +90,12 @@ #define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31) #define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17) #define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18) -#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | 19) -#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | 20) -#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | 21) -#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | 22) -#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | 23) -#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | 24) +#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19) +#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20) +#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21) +#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22) +#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 23) +#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24) #define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25) #define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26) #define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27) diff --git a/arch/arm/plat-mxc/include/mach/mx50.h b/arch/arm/plat-mxc/include/mach/mx50.h index aaec2a6e7b3a..5f2da75a47f4 100644 --- a/arch/arm/plat-mxc/include/mach/mx50.h +++ b/arch/arm/plat-mxc/include/mach/mx50.h @@ -282,4 +282,8 @@ #define MX50_INT_APBHDMA_CHAN6 116 #define MX50_INT_APBHDMA_CHAN7 117 +#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) +extern int mx50_revision(void); +#endif + #endif /* ifndef __MACH_MX50_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h index 1eb339e6c857..dede19a766ff 100644 --- a/arch/arm/plat-mxc/include/mach/mx51.h +++ b/arch/arm/plat-mxc/include/mach/mx51.h @@ -347,6 +347,7 @@ #if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) extern int mx51_revision(void); +extern void mx51_display_revision(void); #endif /* tape-out 1 defines */ diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h index 7e072637eefa..1aea818d9d31 100644 --- a/arch/arm/plat-mxc/include/mach/mxc.h +++ b/arch/arm/plat-mxc/include/mach/mxc.h @@ -51,6 +51,20 @@ #define IMX_CHIP_REVISION_3_3 0x33 #define IMX_CHIP_REVISION_UNKNOWN 0xff +#define IMX_CHIP_REVISION_1_0_STRING "1.0" +#define IMX_CHIP_REVISION_1_1_STRING "1.1" +#define IMX_CHIP_REVISION_1_2_STRING "1.2" +#define IMX_CHIP_REVISION_1_3_STRING "1.3" +#define IMX_CHIP_REVISION_2_0_STRING "2.0" +#define IMX_CHIP_REVISION_2_1_STRING "2.1" +#define IMX_CHIP_REVISION_2_2_STRING "2.2" +#define IMX_CHIP_REVISION_2_3_STRING "2.3" +#define IMX_CHIP_REVISION_3_0_STRING "3.0" +#define IMX_CHIP_REVISION_3_1_STRING "3.1" +#define IMX_CHIP_REVISION_3_2_STRING "3.2" +#define IMX_CHIP_REVISION_3_3_STRING "3.3" +#define IMX_CHIP_REVISION_UNKNOWN_STRING "unknown" + #ifndef __ASSEMBLY__ extern unsigned int __mxc_cpu_type; #endif @@ -181,6 +195,15 @@ struct cpu_op { u32 cpu_rate; }; +int tzic_enable_wake(int is_idle); +enum mxc_cpu_pwr_mode { + WAIT_CLOCKED, /* wfi only */ + WAIT_UNCLOCKED, /* WAIT */ + WAIT_UNCLOCKED_POWER_OFF, /* WAIT + SRPG */ + STOP_POWER_ON, /* just STOP */ + STOP_POWER_OFF, /* STOP + SRPG */ +}; + extern struct cpu_op *(*get_cpu_op)(int *op); #endif diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h index 95be51bfe9a9..0417da9f710d 100644 --- a/arch/arm/plat-mxc/include/mach/system.h +++ b/arch/arm/plat-mxc/include/mach/system.h @@ -20,6 +20,8 @@ #include <mach/hardware.h> #include <mach/common.h> +extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode); + static inline void arch_idle(void) { #ifdef CONFIG_ARCH_MXC91231 @@ -54,7 +56,9 @@ static inline void arch_idle(void) "orr %0, %0, #0x00000004\n" "mcr p15, 0, %0, c1, c0, 0\n" : "=r" (reg)); - } else + } else if (cpu_is_mx51()) + mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); + else cpu_do_idle(); } diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 9f0c2610595e..2237ff8b434f 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -27,6 +27,7 @@ #include <linux/clk.h> #include <mach/hardware.h> +#include <asm/sched_clock.h> #include <asm/mach/time.h> #include <mach/common.h> @@ -105,6 +106,11 @@ static void gpt_irq_acknowledge(void) __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT); } +static cycle_t dummy_get_cycles(struct clocksource *cs) +{ + return 0; +} + static cycle_t mx1_2_get_cycles(struct clocksource *cs) { return __raw_readl(timer_base + MX1_2_TCN); @@ -118,18 +124,35 @@ static cycle_t v2_get_cycles(struct clocksource *cs) static struct clocksource clocksource_mxc = { .name = "mxc_timer1", .rating = 200, - .read = mx1_2_get_cycles, + .read = dummy_get_cycles, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static DEFINE_CLOCK_DATA(cd); +unsigned long long notrace sched_clock(void) +{ + cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); + + return cyc_to_sched_clock(&cd, cyc, (u32)~0); +} + +static void notrace mxc_update_sched_clock(void) +{ + cycle_t cyc = clocksource_mxc.read(&clocksource_mxc); + update_sched_clock(&cd, cyc, (u32)~0); +} + static int __init mxc_clocksource_init(struct clk *timer_clk) { unsigned int c = clk_get_rate(timer_clk); if (timer_is_v2()) clocksource_mxc.read = v2_get_cycles; + else + clocksource_mxc.read = mx1_2_get_cycles; + init_sched_clock(&cd, mxc_update_sched_clock, 32, c); clocksource_register_hz(&clocksource_mxc, c); return 0; diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 49642b59f73d..e9d689b7c833 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -10,7 +10,6 @@ config AVR32 select GENERIC_IRQ_PROBE select HARDIRQS_SW_RESEND select GENERIC_IRQ_SHOW - select GENERIC_HARDIRQS_NO_DEPRECATED help AVR32 is a high-performance 32-bit RISC microprocessor core, designed for cost-sensitive embedded applications, with particular diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index 37534103574e..f308e1ddc629 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c @@ -282,7 +282,7 @@ static struct irq_chip gpio_irqchip = { static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { - struct pio_device *pio = get_irq_desc_chip_data(desc); + struct pio_device *pio = irq_desc_get_chip_data(desc); unsigned gpio_irq; gpio_irq = (unsigned) irq_get_handler_data(irq); diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 672c21632f2f..8addb1220b4f 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -34,7 +34,6 @@ config BLACKFIN select GENERIC_ATOMIC64 select GENERIC_IRQ_PROBE select IRQ_PER_CPU if SMP - select GENERIC_HARDIRQS_NO_DEPRECATED config GENERIC_CSUM def_bool y diff --git a/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig index 362f59dd5228..ad0881ba30af 100644 --- a/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig +++ b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig @@ -46,7 +46,6 @@ CONFIG_UNIX=y # CONFIG_WIRELESS is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig index 6883803e6ca8..580bf4296a14 100644 --- a/arch/blackfin/configs/BF538-EZKIT_defconfig +++ b/arch/blackfin/configs/BF538-EZKIT_defconfig @@ -70,7 +70,6 @@ CONFIG_MTD_ROM=m CONFIG_MTD_PHYSMAP=m CONFIG_MTD_NAND=m CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_NETDEVICES=y CONFIG_PHYLIB=y CONFIG_SMSC_PHY=y diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig index b7c8451f26ac..77a27e31d6d1 100644 --- a/arch/blackfin/configs/BF561-ACVILON_defconfig +++ b/arch/blackfin/configs/BF561-ACVILON_defconfig @@ -63,7 +63,6 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=16384 -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y diff --git a/arch/blackfin/configs/BlackStamp_defconfig b/arch/blackfin/configs/BlackStamp_defconfig index 97ebe09a7370..85014319672c 100644 --- a/arch/blackfin/configs/BlackStamp_defconfig +++ b/arch/blackfin/configs/BlackStamp_defconfig @@ -58,6 +58,7 @@ CONFIG_MTD_M25P80=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT25=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig index c2457543e58c..dbf750cd2db8 100644 --- a/arch/blackfin/configs/CM-BF527_defconfig +++ b/arch/blackfin/configs/CM-BF527_defconfig @@ -64,7 +64,6 @@ CONFIG_MTD_ROM=m CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_GPIO_ADDR=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOWLEVEL is not set diff --git a/arch/blackfin/configs/CM-BF533_defconfig b/arch/blackfin/configs/CM-BF533_defconfig index baf1c1573e5e..07ffbdae34ee 100644 --- a/arch/blackfin/configs/CM-BF533_defconfig +++ b/arch/blackfin/configs/CM-BF533_defconfig @@ -44,7 +44,6 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_RAM=y CONFIG_MTD_PHYSMAP=y -# CONFIG_MISC_DEVICES is not set CONFIG_NETDEVICES=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig index df267588efec..31d954216c05 100644 --- a/arch/blackfin/configs/CM-BF548_defconfig +++ b/arch/blackfin/configs/CM-BF548_defconfig @@ -63,7 +63,6 @@ CONFIG_MTD_RAM=y CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_SCSI=m CONFIG_BLK_DEV_SD=m # CONFIG_SCSI_LOWLEVEL is not set diff --git a/arch/blackfin/configs/DNP5370_defconfig b/arch/blackfin/configs/DNP5370_defconfig index f50313657f3e..b192acfae386 100644 --- a/arch/blackfin/configs/DNP5370_defconfig +++ b/arch/blackfin/configs/DNP5370_defconfig @@ -55,7 +55,6 @@ CONFIG_MTD_NAND=y CONFIG_MTD_NAND_PLATFORM=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -# CONFIG_MISC_DEVICES is not set CONFIG_NETDEVICES=y CONFIG_DAVICOM_PHY=y CONFIG_NET_ETHERNET=y diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig index 7450127b6455..06e9f497faed 100644 --- a/arch/blackfin/configs/H8606_defconfig +++ b/arch/blackfin/configs/H8606_defconfig @@ -45,6 +45,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_M25P80=y # CONFIG_M25PXX_USE_FAST_READ is not set CONFIG_BLK_DEV_RAM=y +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT25=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y diff --git a/arch/blackfin/configs/SRV1_defconfig b/arch/blackfin/configs/SRV1_defconfig index 853809510ee9..12e66cd7cdaa 100644 --- a/arch/blackfin/configs/SRV1_defconfig +++ b/arch/blackfin/configs/SRV1_defconfig @@ -48,6 +48,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y CONFIG_MTD_UCLINUX=y CONFIG_MTD_NAND=m CONFIG_BLK_DEV_RAM=y +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT25=m CONFIG_NETDEVICES=y # CONFIG_NETDEV_1000 is not set diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h index 49762c6bb0d5..8a0fed16058f 100644 --- a/arch/blackfin/include/asm/bitops.h +++ b/arch/blackfin/include/asm/bitops.h @@ -25,7 +25,6 @@ #include <asm-generic/bitops/const_hweight.h> #include <asm-generic/bitops/lock.h> -#include <asm-generic/bitops/le.h> #include <asm-generic/bitops/ext2-atomic.h> #ifndef CONFIG_SMP @@ -113,6 +112,9 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) #endif /* CONFIG_SMP */ +/* Needs to be after test_bit and friends */ +#include <asm-generic/bitops/le.h> + /* * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index a6dfa6b71e63..35e350cad9d9 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c @@ -4,7 +4,7 @@ * Licensed under the GPL-2 or later */ -#define pr_fmt(fmt) "module %s: " fmt +#define pr_fmt(fmt) "module %s: " fmt, mod->name #include <linux/moduleloader.h> #include <linux/elf.h> @@ -57,8 +57,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_inst_sram_alloc(s->sh_size); mod->arch.text_l1 = dest; if (dest == NULL) { - pr_err("L1 inst memory allocation failed\n", - mod->name); + pr_err("L1 inst memory allocation failed\n"); return -1; } dma_memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -70,8 +69,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_sram_alloc(s->sh_size); mod->arch.data_a_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n", - mod->name); + pr_err("L1 data memory allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -83,8 +81,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_sram_zalloc(s->sh_size); mod->arch.bss_a_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n", - mod->name); + pr_err("L1 data memory allocation failed\n"); return -1; } @@ -93,8 +90,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_B_sram_alloc(s->sh_size); mod->arch.data_b_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n", - mod->name); + pr_err("L1 data memory allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -104,8 +100,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l1_data_B_sram_alloc(s->sh_size); mod->arch.bss_b_l1 = dest; if (dest == NULL) { - pr_err("L1 data memory allocation failed\n", - mod->name); + pr_err("L1 data memory allocation failed\n"); return -1; } memset(dest, 0, s->sh_size); @@ -117,8 +112,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_alloc(s->sh_size); mod->arch.text_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n", - mod->name); + pr_err("L2 SRAM allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -130,8 +124,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_alloc(s->sh_size); mod->arch.data_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n", - mod->name); + pr_err("L2 SRAM allocation failed\n"); return -1; } memcpy(dest, (void *)s->sh_addr, s->sh_size); @@ -143,8 +136,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, dest = l2_sram_zalloc(s->sh_size); mod->arch.bss_l2 = dest; if (dest == NULL) { - pr_err("L2 SRAM allocation failed\n", - mod->name); + pr_err("L2 SRAM allocation failed\n"); return -1; } @@ -160,9 +152,9 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, int apply_relocate(Elf_Shdr * sechdrs, const char *strtab, - unsigned int symindex, unsigned int relsec, struct module *me) + unsigned int symindex, unsigned int relsec, struct module *mod) { - pr_err(".rel unsupported\n", me->name); + pr_err(".rel unsupported\n"); return -ENOEXEC; } @@ -186,7 +178,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, Elf32_Sym *sym; unsigned long location, value, size; - pr_debug("applying relocate section %u to %u\n", mod->name, + pr_debug("applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { @@ -203,14 +195,14 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, #ifdef CONFIG_SMP if (location >= COREB_L1_DATA_A_START) { - pr_err("cannot relocate in L1: %u (SMP kernel)", - mod->name, ELF32_R_TYPE(rel[i].r_info)); + pr_err("cannot relocate in L1: %u (SMP kernel)\n", + ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } #endif pr_debug("location is %lx, value is %lx type is %d\n", - mod->name, location, value, ELF32_R_TYPE(rel[i].r_info)); + location, value, ELF32_R_TYPE(rel[i].r_info)); switch (ELF32_R_TYPE(rel[i].r_info)) { @@ -230,11 +222,11 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, case R_BFIN_PCREL12_JUMP_S: case R_BFIN_PCREL10: pr_err("unsupported relocation: %u (no -mlong-calls?)\n", - mod->name, ELF32_R_TYPE(rel[i].r_info)); + ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; default: - pr_err("unknown relocation: %u\n", mod->name, + pr_err("unknown relocation: %u\n", ELF32_R_TYPE(rel[i].r_info)); return -ENOEXEC; } @@ -251,8 +243,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, isram_memcpy((void *)location, &value, size); break; default: - pr_err("invalid relocation for %#lx\n", - mod->name, location); + pr_err("invalid relocation for %#lx\n", location); return -ENOEXEC; } } diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 617925ddd142..a6d03069d0ff 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -55,7 +55,6 @@ config CRIS default y select HAVE_IDE select HAVE_GENERIC_HARDIRQS - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW config HZ diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index 6db8aea5667f..064f62196745 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -7,7 +7,6 @@ config FRV select HAVE_PERF_EVENTS select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW - select GENERIC_HARDIRQS_NO_DEPRECATED config ZONE_DMA bool diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index 931a1ac99ff1..e20322ffcaf8 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -3,7 +3,6 @@ config H8300 default y select HAVE_IDE select HAVE_GENERIC_HARDIRQS - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW config SYMBOL_PREFIX diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 7f399f9d99c7..139c018dbbf9 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -412,7 +412,7 @@ sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info) pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type]; /* Don't force an interrupt if the irq has been disabled */ - if (!irqd_irq_disabled(sn_irq_info->irq_irq) && + if (!irqd_irq_disabled(irq_get_irq_data(sn_irq_info->irq_irq)) && pci_provider && pci_provider->force_interrupt) (*pci_provider->force_interrupt)(sn_irq_info); } diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c index c76d8dc3aea3..7aab87f48060 100644 --- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c +++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c @@ -45,38 +45,6 @@ static int licenseID_open(struct inode *inode, struct file *file) return single_open(file, licenseID_show, NULL); } -/* - * Enable forced interrupt by default. - * When set, the sn interrupt handler writes the force interrupt register on - * the bridge chip. The hardware will then send an interrupt message if the - * interrupt line is active. This mimics a level sensitive interrupt. - */ -extern int sn_force_interrupt_flag; - -static int sn_force_interrupt_show(struct seq_file *s, void *p) -{ - seq_printf(s, "Force interrupt is %s\n", - sn_force_interrupt_flag ? "enabled" : "disabled"); - return 0; -} - -static ssize_t sn_force_interrupt_write_proc(struct file *file, - const char __user *buffer, size_t count, loff_t *data) -{ - char val; - - if (copy_from_user(&val, buffer, 1)) - return -EFAULT; - - sn_force_interrupt_flag = (val == '0') ? 0 : 1; - return count; -} - -static int sn_force_interrupt_open(struct inode *inode, struct file *file) -{ - return single_open(file, sn_force_interrupt_show, NULL); -} - static int coherence_id_show(struct seq_file *s, void *p) { seq_printf(s, "%d\n", partition_coherence_id()); @@ -114,14 +82,6 @@ static const struct file_operations proc_license_id_fops = { .release = single_release, }; -static const struct file_operations proc_sn_force_intr_fops = { - .open = sn_force_interrupt_open, - .read = seq_read, - .write = sn_force_interrupt_write_proc, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations proc_coherence_id_fops = { .open = coherence_id_open, .read = seq_read, @@ -149,8 +109,6 @@ void register_sn_procfs(void) proc_create("system_serial_number", 0444, sgi_proc_dir, &proc_system_sn_fops); proc_create("licenseID", 0444, sgi_proc_dir, &proc_license_id_fops); - proc_create("sn_force_interrupt", 0644, sgi_proc_dir, - &proc_sn_force_intr_fops); proc_create("coherence_id", 0444, sgi_proc_dir, &proc_coherence_id_fops); proc_create("sn_topology", 0444, sgi_proc_dir, &proc_sn_topo_fops); diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index b28d0908a402..736b808d2291 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -8,7 +8,6 @@ config M32R select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZMA select HAVE_GENERIC_HARDIRQS - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 6e056d3c5d01..75531da02a40 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -5,7 +5,6 @@ config M68K select HAVE_AOUT if MMU select GENERIC_ATOMIC64 if MMU select HAVE_GENERIC_HARDIRQS if !MMU - select GENERIC_HARDIRQS_NO_DEPRECATED if !MMU config RWSEM_GENERIC_SPINLOCK bool diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index c49c326e7af1..851b3bf6e962 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -17,7 +17,6 @@ config MICROBLAZE select OF_EARLY_FLATTREE select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW config SWAP diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h index d770b00ec6b1..30edd61a6b8f 100644 --- a/arch/microblaze/include/asm/unistd.h +++ b/arch/microblaze/include/asm/unistd.h @@ -386,8 +386,12 @@ #define __NR_fanotify_init 368 #define __NR_fanotify_mark 369 #define __NR_prlimit64 370 +#define __NR_name_to_handle_at 371 +#define __NR_open_by_handle_at 372 +#define __NR_clock_adjtime 373 +#define __NR_syncfs 374 -#define __NR_syscalls 371 +#define __NR_syscalls 375 #ifdef __KERNEL__ #ifndef __ASSEMBLY__ diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index f0cb5c26c81c..494b63b72dd7 100644 --- a/arch/microblaze/kernel/Makefile +++ b/arch/microblaze/kernel/Makefile @@ -10,6 +10,7 @@ CFLAGS_REMOVE_early_printk.o = -pg CFLAGS_REMOVE_selfmod.o = -pg CFLAGS_REMOVE_heartbeat.o = -pg CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_process.o = -pg endif extra-y := head.o vmlinux.lds diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c index 515feb404555..357d56abe24a 100644 --- a/arch/microblaze/kernel/ftrace.c +++ b/arch/microblaze/kernel/ftrace.c @@ -51,6 +51,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) : "r" (parent), "r" (return_hooker) ); + flush_dcache_range((u32)parent, (u32)parent + 4); + flush_icache_range((u32)parent, (u32)parent + 4); + if (unlikely(faulted)) { ftrace_graph_stop(); WARN_ON(1); @@ -95,6 +98,9 @@ static int ftrace_modify_code(unsigned long addr, unsigned int value) if (unlikely(faulted)) return -EFAULT; + flush_dcache_range(addr, addr + 4); + flush_icache_range(addr, addr + 4); + return 0; } @@ -195,8 +201,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func) ret += ftrace_modify_code((unsigned long)&ftrace_caller, MICROBLAZE_NOP); - /* All changes are done - lets do caches consistent */ - flush_icache(); return ret; } @@ -210,7 +214,6 @@ int ftrace_enable_ftrace_graph_caller(void) old_jump = *(unsigned int *)ip; /* save jump over instruction */ ret = ftrace_modify_code(ip, MICROBLAZE_NOP); - flush_icache(); pr_debug("%s: Replace instruction: 0x%x\n", __func__, old_jump); return ret; @@ -222,7 +225,6 @@ int ftrace_disable_ftrace_graph_caller(void) unsigned long ip = (unsigned long)(&ftrace_call_graph); ret = ftrace_modify_code(ip, old_jump); - flush_icache(); pr_debug("%s\n", __func__); return ret; diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index 5ba7e162833b..c88f066f41bd 100644 --- a/arch/microblaze/kernel/intc.c +++ b/arch/microblaze/kernel/intc.c @@ -158,11 +158,11 @@ void __init init_IRQ(void) for (i = 0; i < nr_irq; ++i) { if (intr_type & (0x00000001 << i)) { irq_set_chip_and_handler_name(i, &intc_dev, - handle_edge_irq, intc_dev.name); + handle_edge_irq, "edge"); irq_clear_status_flags(i, IRQ_LEVEL); } else { irq_set_chip_and_handler_name(i, &intc_dev, - handle_level_irq, intc_dev.name); + handle_level_irq, "level"); irq_set_status_flags(i, IRQ_LEVEL); } } diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S index e88a930fd1e3..85cea81d1ca1 100644 --- a/arch/microblaze/kernel/syscall_table.S +++ b/arch/microblaze/kernel/syscall_table.S @@ -375,3 +375,7 @@ ENTRY(sys_call_table) .long sys_fanotify_init .long sys_fanotify_mark .long sys_prlimit64 /* 370 */ + .long sys_name_to_handle_at + .long sys_open_by_handle_at + .long sys_clock_adjtime + .long sys_syncfs diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index f1fcbff3da25..10c320aa908b 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -2,6 +2,12 @@ # Makefile # +ifdef CONFIG_FUNCTION_TRACER +CFLAGS_REMOVE_ashldi3.o = -pg +CFLAGS_REMOVE_ashrdi3.o = -pg +CFLAGS_REMOVE_lshrdi3.o = -pg +endif + lib-y := memset.o ifeq ($(CONFIG_OPT_LIB_ASM),y) diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index a523c94fa698..feaf09cc8632 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -2,7 +2,6 @@ config MN10300 def_bool y select HAVE_OPROFILE select HAVE_GENERIC_HARDIRQS - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_KGDB diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 9b1f427cdc37..69ff049c8571 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -15,7 +15,6 @@ config PARISC select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select IRQ_PER_CPU - select GENERIC_HARDIRQS_NO_DEPRECATED help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d0e8a1dbf822..b6ff882f695b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -138,7 +138,6 @@ config PPC select HAVE_GENERIC_HARDIRQS select HAVE_SPARSE_IRQ select IRQ_PER_CPU - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW_LEVEL diff --git a/arch/powerpc/boot/dts/p1020rdb.dts b/arch/powerpc/boot/dts/p1020rdb.dts index 22f64b62d7f6..e0668f877794 100644 --- a/arch/powerpc/boot/dts/p1020rdb.dts +++ b/arch/powerpc/boot/dts/p1020rdb.dts @@ -1,7 +1,7 @@ /* * P1020 RDB Device Tree Source * - * Copyright 2009 Freescale Semiconductor Inc. + * Copyright 2009-2011 Freescale Semiconductor Inc. * * 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 @@ -553,7 +553,7 @@ reg = <0 0xffe09000 0 0x1000>; bus-range = <0 255>; ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>; + 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <16 2>; @@ -580,8 +580,8 @@ #address-cells = <3>; reg = <0 0xffe0a000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; + ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <16 2>; @@ -590,8 +590,8 @@ #size-cells = <2>; #address-cells = <3>; device_type = "pci"; - ranges = <0x2000000 0x0 0xc0000000 - 0x2000000 0x0 0xc0000000 + ranges = <0x2000000 0x0 0x80000000 + 0x2000000 0x0 0x80000000 0x0 0x20000000 0x1000000 0x0 0x0 diff --git a/arch/powerpc/boot/dts/p2020rdb.dts b/arch/powerpc/boot/dts/p2020rdb.dts index da4cb0d8d215..e2d48fd4416e 100644 --- a/arch/powerpc/boot/dts/p2020rdb.dts +++ b/arch/powerpc/boot/dts/p2020rdb.dts @@ -1,7 +1,7 @@ /* * P2020 RDB Device Tree Source * - * Copyright 2009 Freescale Semiconductor Inc. + * Copyright 2009-2011 Freescale Semiconductor Inc. * * 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 @@ -537,7 +537,7 @@ reg = <0 0xffe09000 0 0x1000>; bus-range = <0 255>; ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>; + 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <25 2>; @@ -564,8 +564,8 @@ #address-cells = <3>; reg = <0 0xffe0a000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; + ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <26 2>; @@ -574,8 +574,8 @@ #size-cells = <2>; #address-cells = <3>; device_type = "pci"; - ranges = <0x2000000 0x0 0xc0000000 - 0x2000000 0x0 0xc0000000 + ranges = <0x2000000 0x0 0x80000000 + 0x2000000 0x0 0x80000000 0x0 0x20000000 0x1000000 0x0 0x0 diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts index 0fe93d0c8b2e..b69c3a5dc858 100644 --- a/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts +++ b/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts @@ -6,7 +6,7 @@ * This dts file allows core0 to have memory, l2, i2c, spi, gpio, dma1, usb, * eth1, eth2, sdhc, crypto, global-util, pci0. * - * Copyright 2009 Freescale Semiconductor Inc. + * Copyright 2009-2011 Freescale Semiconductor Inc. * * 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 @@ -342,7 +342,7 @@ reg = <0 0xffe09000 0 0x1000>; bus-range = <0 255>; ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>; + 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <25 2>; diff --git a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts b/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts index e95a51285328..7a31d46c01b0 100644 --- a/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts +++ b/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts @@ -7,7 +7,7 @@ * * Please note to add "-b 1" for core1's dts compiling. * - * Copyright 2009 Freescale Semiconductor Inc. + * Copyright 2009-2011 Freescale Semiconductor Inc. * * 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 @@ -162,8 +162,8 @@ #address-cells = <3>; reg = <0 0xffe0a000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; + ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <26 2>; @@ -172,8 +172,8 @@ #size-cells = <2>; #address-cells = <3>; device_type = "pci"; - ranges = <0x2000000 0x0 0xc0000000 - 0x2000000 0x0 0xc0000000 + ranges = <0x2000000 0x0 0x80000000 + 0x2000000 0x0 0x80000000 0x0 0x20000000 0x1000000 0x0 0x0 diff --git a/arch/powerpc/configs/44x/warp_defconfig b/arch/powerpc/configs/44x/warp_defconfig index 6cf9d6614805..abf74dc1f79c 100644 --- a/arch/powerpc/configs/44x/warp_defconfig +++ b/arch/powerpc/configs/44x/warp_defconfig @@ -47,6 +47,7 @@ CONFIG_MTD_NAND_NDFC=y CONFIG_MTD_UBI=y CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_RAM=y +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT24=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig index 6828eda02bdc..0c7de9620ea6 100644 --- a/arch/powerpc/configs/52xx/motionpro_defconfig +++ b/arch/powerpc/configs/52xx/motionpro_defconfig @@ -43,6 +43,7 @@ CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y CONFIG_SCSI_TGT=y CONFIG_BLK_DEV_SD=y diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig index 4b2441244eab..d41857a5152d 100644 --- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig +++ b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig @@ -85,6 +85,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_MISC_DEVICES=y CONFIG_DS1682=y CONFIG_IDE=y CONFIG_BLK_DEV_IDECS=y diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig index a360ba44b928..38303ec11bcd 100644 --- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig +++ b/arch/powerpc/configs/86xx/gef_sbc310_defconfig @@ -85,6 +85,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_MISC_DEVICES=y CONFIG_DS1682=y CONFIG_IDE=y CONFIG_BLK_DEV_IDECS=y diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig index be2829dd129f..98533973d20f 100644 --- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig +++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig @@ -138,6 +138,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_MISC_DEVICES=y CONFIG_DS1682=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig index 0c9c7ed7ec75..b614508d6fd2 100644 --- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig +++ b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig @@ -63,6 +63,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y diff --git a/arch/powerpc/configs/e55xx_smp_defconfig b/arch/powerpc/configs/e55xx_smp_defconfig index 06f95492afc7..9fa1613e5e2b 100644 --- a/arch/powerpc/configs/e55xx_smp_defconfig +++ b/arch/powerpc/configs/e55xx_smp_defconfig @@ -32,6 +32,7 @@ CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_MOUSEDEV is not set diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig index f39d0cf876dd..8a874b999867 100644 --- a/arch/powerpc/configs/linkstation_defconfig +++ b/arch/powerpc/configs/linkstation_defconfig @@ -78,6 +78,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=m CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index 62db8a3df162..c02bbb2fddf8 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig @@ -61,6 +61,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=1 CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_BLK_DEV_XIP=y +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT24=y CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index 7376e27b8ed4..e63f537b854a 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -52,6 +52,7 @@ CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_AT24=y CONFIG_SCSI_TGT=y CONFIG_BLK_DEV_SD=y diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index 99a19d1e9bf8..c06a86c33098 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -82,6 +82,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig index c636f23f8c92..942ced90557c 100644 --- a/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -84,6 +84,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig index 55b54318fef6..038a308cbfc4 100644 --- a/arch/powerpc/configs/mpc86xx_defconfig +++ b/arch/powerpc/configs/mpc86xx_defconfig @@ -66,6 +66,7 @@ CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_NBD=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_ST=y diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index edd2d54c8196..f4deb0b78cf0 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -59,6 +59,7 @@ CONFIG_PROC_DEVICETREE=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_MISC_DEVICES=y CONFIG_EEPROM_LEGACY=y CONFIG_IDE=y CONFIG_BLK_DEV_IDECD=y diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 9d64a6822d86..0a10fb009ef7 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -398,6 +398,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_CDROM_PKTCDVD=m CONFIG_VIRTIO_BLK=m CONFIG_BLK_DEV_HD=y +CONFIG_MISC_DEVICES=y CONFIG_ENCLOSURE_SERVICES=m CONFIG_SENSORS_TSL2550=m CONFIG_EEPROM_AT24=m diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 9c3f22c6cde1..249ddd0a27cd 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -189,6 +189,7 @@ CONFIG_TIGON3=y CONFIG_BNX2=m CONFIG_CHELSIO_T1=m CONFIG_CHELSIO_T3=m +CONFIG_CHELSIO_T4=m CONFIG_EHEA=y CONFIG_IXGBE=m CONFIG_IXGB=m @@ -255,6 +256,8 @@ CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_EHCA=m +CONFIG_INFINIBAND_CXGB3=m +CONFIG_INFINIBAND_CXGB4=m CONFIG_MLX4_INFINIBAND=m CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_CM=y diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 6d2416a85709..dd70fac57ec8 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h @@ -42,6 +42,7 @@ extern void __dma_free_coherent(size_t size, void *vaddr); extern void __dma_sync(void *vaddr, size_t size, int direction); extern void __dma_sync_page(struct page *page, unsigned long offset, size_t size, int direction); +extern unsigned long __dma_get_coherent_pfn(unsigned long cpu_addr); #else /* ! CONFIG_NOT_COHERENT_CACHE */ /* @@ -198,6 +199,11 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) +extern int dma_mmap_coherent(struct device *, struct vm_area_struct *, + void *, dma_addr_t, size_t); +#define ARCH_HAS_DMA_MMAP_COHERENT + + static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index fe56a23e1ff0..e4f01915fbb0 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -35,9 +35,9 @@ struct smp_ops_t { int (*probe)(void); void (*kick_cpu)(int nr); void (*setup_cpu)(int nr); + void (*bringup_done)(void); void (*take_timebase)(void); void (*give_timebase)(void); - int (*cpu_enable)(unsigned int nr); int (*cpu_disable)(void); void (*cpu_die)(unsigned int nr); int (*cpu_bootable)(unsigned int nr); @@ -267,7 +267,6 @@ struct machdep_calls { extern void e500_idle(void); extern void power4_idle(void); -extern void power4_cpu_offline_powersave(void); extern void ppc6xx_idle(void); extern void book3e_idle(void); diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h index acac35d5b382..ae7b3efec8e5 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h @@ -27,7 +27,7 @@ #define STE_VSID_SHIFT 12 /* Location of cpu0's segment table */ -#define STAB0_PAGE 0x6 +#define STAB0_PAGE 0x8 #define STAB0_OFFSET (STAB0_PAGE << 12) #define STAB0_PHYS_ADDR (STAB0_OFFSET + PHYSICAL_START) diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index da4b20008541..2cd664ef0a5e 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -100,7 +100,7 @@ extern phys_addr_t kernstart_addr; #endif #ifdef CONFIG_FLATMEM -#define ARCH_PFN_OFFSET (MEMORY_START >> PAGE_SHIFT) +#define ARCH_PFN_OFFSET ((unsigned long)(MEMORY_START >> PAGE_SHIFT)) #define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr) #endif diff --git a/arch/powerpc/include/asm/qe_ic.h b/arch/powerpc/include/asm/qe_ic.h index 9e2cb2019161..f706164b0bd0 100644 --- a/arch/powerpc/include/asm/qe_ic.h +++ b/arch/powerpc/include/asm/qe_ic.h @@ -81,7 +81,7 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high); static inline void qe_ic_cascade_low_ipic(unsigned int irq, struct irq_desc *desc) { - struct qe_ic *qe_ic = get_irq_desc_data(desc); + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); if (cascade_irq != NO_IRQ) @@ -91,7 +91,7 @@ static inline void qe_ic_cascade_low_ipic(unsigned int irq, static inline void qe_ic_cascade_high_ipic(unsigned int irq, struct irq_desc *desc) { - struct qe_ic *qe_ic = get_irq_desc_data(desc); + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); if (cascade_irq != NO_IRQ) @@ -101,9 +101,9 @@ static inline void qe_ic_cascade_high_ipic(unsigned int irq, static inline void qe_ic_cascade_low_mpic(unsigned int irq, struct irq_desc *desc) { - struct qe_ic *qe_ic = get_irq_desc_data(desc); + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); - struct irq_chip *chip = get_irq_desc_chip(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); if (cascade_irq != NO_IRQ) generic_handle_irq(cascade_irq); @@ -114,9 +114,9 @@ static inline void qe_ic_cascade_low_mpic(unsigned int irq, static inline void qe_ic_cascade_high_mpic(unsigned int irq, struct irq_desc *desc) { - struct qe_ic *qe_ic = get_irq_desc_data(desc); + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); - struct irq_chip *chip = get_irq_desc_chip(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); if (cascade_irq != NO_IRQ) generic_handle_irq(cascade_irq); @@ -127,9 +127,9 @@ static inline void qe_ic_cascade_high_mpic(unsigned int irq, static inline void qe_ic_cascade_muxed_mpic(unsigned int irq, struct irq_desc *desc) { - struct qe_ic *qe_ic = get_irq_desc_data(desc); + struct qe_ic *qe_ic = irq_desc_get_handler_data(desc); unsigned int cascade_irq; - struct irq_chip *chip = get_irq_desc_chip(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); cascade_irq = qe_ic_get_high_irq(qe_ic); if (cascade_irq == NO_IRQ) diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 86ad8128963a..3b1a9b707362 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -110,7 +110,7 @@ #define SPRN_MAS2 0x272 /* MMU Assist Register 2 */ #define SPRN_MAS3 0x273 /* MMU Assist Register 3 */ #define SPRN_MAS4 0x274 /* MMU Assist Register 4 */ -#define SPRN_MAS5 0x275 /* MMU Assist Register 5 */ +#define SPRN_MAS5 0x153 /* MMU Assist Register 5 */ #define SPRN_MAS6 0x276 /* MMU Assist Register 6 */ #define SPRN_PID1 0x279 /* Process ID Register 1 */ #define SPRN_PID2 0x27A /* Process ID Register 2 */ diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 66e237bbe15f..a902a0d3ae0d 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -36,15 +36,16 @@ extern void cpu_die(void); extern void smp_send_debugger_break(int cpu); extern void smp_message_recv(int); +extern void start_secondary_resume(void); DECLARE_PER_CPU(unsigned int, cpu_pvr); #ifdef CONFIG_HOTPLUG_CPU -extern void fixup_irqs(const struct cpumask *map); +extern void migrate_irqs(void); int generic_cpu_disable(void); -int generic_cpu_enable(unsigned int cpu); void generic_cpu_die(unsigned int cpu); void generic_mach_cpu_die(void); +void generic_set_cpu_dead(unsigned int cpu); #endif #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h index aa0f1ebb4aaf..60f64b132bd4 100644 --- a/arch/powerpc/include/asm/systbl.h +++ b/arch/powerpc/include/asm/systbl.h @@ -348,3 +348,7 @@ COMPAT_SYS_SPU(sendmsg) COMPAT_SYS_SPU(recvmsg) COMPAT_SYS_SPU(recvmmsg) SYSCALL_SPU(accept4) +SYSCALL_SPU(name_to_handle_at) +COMPAT_SYS_SPU(open_by_handle_at) +COMPAT_SYS_SPU(clock_adjtime) +SYSCALL_SPU(syncfs) diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h index 6151937657f6..3c215648ce6d 100644 --- a/arch/powerpc/include/asm/unistd.h +++ b/arch/powerpc/include/asm/unistd.h @@ -367,10 +367,14 @@ #define __NR_recvmsg 342 #define __NR_recvmmsg 343 #define __NR_accept4 344 +#define __NR_name_to_handle_at 345 +#define __NR_open_by_handle_at 346 +#define __NR_clock_adjtime 347 +#define __NR_syncfs 348 #ifdef __KERNEL__ -#define __NR_syscalls 345 +#define __NR_syscalls 349 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 3d569e2aff18..3d3d416339dd 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -163,7 +163,7 @@ static void crash_kexec_prepare_cpus(int cpu) } /* wait for all the CPUs to hit real mode but timeout if they don't come in */ -#ifdef CONFIG_PPC_STD_MMU_64 +#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) static void crash_kexec_wait_realmode(int cpu) { unsigned int msecs; @@ -188,6 +188,8 @@ static void crash_kexec_wait_realmode(int cpu) } mb(); } +#else +static inline void crash_kexec_wait_realmode(int cpu) {} #endif /* @@ -344,9 +346,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) crash_save_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); -#if defined(CONFIG_PPC_STD_MMU_64) && defined(CONFIG_SMP) crash_kexec_wait_realmode(crashing_cpu); -#endif machine_kexec_mask_interrupts(); diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index cf02cad62d9a..d238c082c3c5 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c @@ -179,3 +179,21 @@ static int __init dma_init(void) return 0; } fs_initcall(dma_init); + +int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, size_t size) +{ + unsigned long pfn; + +#ifdef CONFIG_NOT_COHERENT_CACHE + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr); +#else + pfn = page_to_pfn(virt_to_page(cpu_addr)); +#endif + return remap_pfn_range(vma, vma->vm_start, + pfn + vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot); +} +EXPORT_SYMBOL_GPL(dma_mmap_coherent); diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 8a817995b4cd..c532cb2c927a 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -977,20 +977,6 @@ _GLOBAL(do_stab_bolted) rfid b . /* prevent speculative execution */ -/* - * Space for CPU0's segment table. - * - * On iSeries, the hypervisor must fill in at least one entry before - * we get control (with relocate on). The address is given to the hv - * as a page number (see xLparMap below), so this must be at a - * fixed address (the linker can't compute (u64)&initial_stab >> - * PAGE_SHIFT). - */ - . = STAB0_OFFSET /* 0x6000 */ - .globl initial_stab -initial_stab: - .space 4096 - #ifdef CONFIG_PPC_PSERIES /* * Data area reserved for FWNMI option. @@ -1027,3 +1013,17 @@ xLparMap: #ifdef CONFIG_PPC_PSERIES . = 0x8000 #endif /* CONFIG_PPC_PSERIES */ + +/* + * Space for CPU0's segment table. + * + * On iSeries, the hypervisor must fill in at least one entry before + * we get control (with relocate on). The address is given to the hv + * as a page number (see xLparMap above), so this must be at a + * fixed address (the linker can't compute (u64)&initial_stab >> + * PAGE_SHIFT). + */ + . = STAB0_OFFSET /* 0x8000 */ + .globl initial_stab +initial_stab: + .space 4096 diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 98c4b29a56f4..c5c24beb8387 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -890,6 +890,15 @@ __secondary_start: mtspr SPRN_SRR1,r4 SYNC RFI + +_GLOBAL(start_secondary_resume) + /* Reset stack */ + rlwinm r1,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ + addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD + li r3,0 + std r3,0(r1) /* Zero the stack frame pointer */ + bl start_secondary + b . #endif /* CONFIG_SMP */ #ifdef CONFIG_KVM_BOOK3S_HANDLER diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 782f23df7c85..271140b38b6f 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -536,6 +536,13 @@ _GLOBAL(pmac_secondary_start) add r13,r13,r4 /* for this processor. */ mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/ + /* Mark interrupts soft and hard disabled (they might be enabled + * in the PACA when doing hotplug) + */ + li r0,0 + stb r0,PACASOFTIRQEN(r13) + stb r0,PACAHARDIRQEN(r13) + /* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13) subi r1,r1,STACK_FRAME_OVERHEAD diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 5328709eeedc..ba3195478600 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S @@ -53,24 +53,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) isync b 1b -_GLOBAL(power4_cpu_offline_powersave) - /* Go to NAP now */ - mfmsr r7 - rldicl r0,r7,48,1 - rotldi r0,r0,16 - mtmsrd r0,1 /* hard-disable interrupts */ - li r0,1 - li r6,0 - stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */ - stb r6,PACASOFTIRQEN(r13) /* soft-disable irqs */ -BEGIN_FTR_SECTION - DSSALL - sync -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - ori r7,r7,MSR_EE - oris r7,r7,MSR_POW@h - sync - isync - mtmsrd r7 - isync - blr diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 63625e0650b5..f621b7d2d869 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -246,12 +246,13 @@ u64 arch_irq_stat_cpu(unsigned int cpu) } #ifdef CONFIG_HOTPLUG_CPU -void fixup_irqs(const struct cpumask *map) +void migrate_irqs(void) { struct irq_desc *desc; unsigned int irq; static int warned; cpumask_var_t mask; + const struct cpumask *map = cpu_online_mask; alloc_cpumask_var(&mask, GFP_KERNEL); diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index f4adf89d7614..10f0aadee95b 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -203,7 +203,7 @@ void __init free_unused_pacas(void) { int new_size; - new_size = PAGE_ALIGN(sizeof(struct paca_struct) * num_possible_cpus()); + new_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids); if (new_size >= paca_size) return; diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 9d4882a46647..21f30cb68077 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -509,6 +509,9 @@ void __init smp_setup_cpu_maps(void) */ cpu_init_thread_core_maps(nthreads); + /* Now that possible cpus are set, set nr_cpu_ids for later use */ + nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1; + free_unused_pacas(); } #endif /* CONFIG_SMP */ diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 981360509172..cbdbb14be4b0 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -57,6 +57,25 @@ #define DBG(fmt...) #endif + +/* Store all idle threads, this can be reused instead of creating +* a new thread. Also avoids complicated thread destroy functionality +* for idle threads. +*/ +#ifdef CONFIG_HOTPLUG_CPU +/* + * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is + * removed after init for !CONFIG_HOTPLUG_CPU. + */ +static DEFINE_PER_CPU(struct task_struct *, idle_thread_array); +#define get_idle_for_cpu(x) (per_cpu(idle_thread_array, x)) +#define set_idle_for_cpu(x, p) (per_cpu(idle_thread_array, x) = (p)) +#else +static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ; +#define get_idle_for_cpu(x) (idle_thread_array[(x)]) +#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p)) +#endif + struct thread_info *secondary_ti; DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); @@ -238,23 +257,6 @@ static void __devinit smp_store_cpu_info(int id) per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR); } -static void __init smp_create_idle(unsigned int cpu) -{ - struct task_struct *p; - - /* create a process for the processor */ - p = fork_idle(cpu); - if (IS_ERR(p)) - panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p)); -#ifdef CONFIG_PPC64 - paca[cpu].__current = p; - paca[cpu].kstack = (unsigned long) task_thread_info(p) - + THREAD_SIZE - STACK_FRAME_OVERHEAD; -#endif - current_set[cpu] = task_thread_info(p); - task_thread_info(p)->cpu = cpu; -} - void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int cpu; @@ -288,10 +290,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus) max_cpus = NR_CPUS; else max_cpus = 1; - - for_each_possible_cpu(cpu) - if (cpu != boot_cpuid) - smp_create_idle(cpu); } void __devinit smp_prepare_boot_cpu(void) @@ -305,7 +303,7 @@ void __devinit smp_prepare_boot_cpu(void) #ifdef CONFIG_HOTPLUG_CPU /* State of each CPU during hotplug phases */ -DEFINE_PER_CPU(int, cpu_state) = { 0 }; +static DEFINE_PER_CPU(int, cpu_state) = { 0 }; int generic_cpu_disable(void) { @@ -317,30 +315,8 @@ int generic_cpu_disable(void) set_cpu_online(cpu, false); #ifdef CONFIG_PPC64 vdso_data->processorCount--; - fixup_irqs(cpu_online_mask); -#endif - return 0; -} - -int generic_cpu_enable(unsigned int cpu) -{ - /* Do the normal bootup if we haven't - * already bootstrapped. */ - if (system_state != SYSTEM_RUNNING) - return -ENOSYS; - - /* get the target out of it's holding state */ - per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; - smp_wmb(); - - while (!cpu_online(cpu)) - cpu_relax(); - -#ifdef CONFIG_PPC64 - fixup_irqs(cpu_online_mask); - /* counter the irq disable in fixup_irqs */ - local_irq_enable(); #endif + migrate_irqs(); return 0; } @@ -362,37 +338,89 @@ void generic_mach_cpu_die(void) unsigned int cpu; local_irq_disable(); + idle_task_exit(); cpu = smp_processor_id(); printk(KERN_DEBUG "CPU%d offline\n", cpu); __get_cpu_var(cpu_state) = CPU_DEAD; smp_wmb(); while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) cpu_relax(); - set_cpu_online(cpu, true); - local_irq_enable(); +} + +void generic_set_cpu_dead(unsigned int cpu) +{ + per_cpu(cpu_state, cpu) = CPU_DEAD; } #endif -static int __devinit cpu_enable(unsigned int cpu) +struct create_idle { + struct work_struct work; + struct task_struct *idle; + struct completion done; + int cpu; +}; + +static void __cpuinit do_fork_idle(struct work_struct *work) { - if (smp_ops && smp_ops->cpu_enable) - return smp_ops->cpu_enable(cpu); + struct create_idle *c_idle = + container_of(work, struct create_idle, work); + + c_idle->idle = fork_idle(c_idle->cpu); + complete(&c_idle->done); +} + +static int __cpuinit create_idle(unsigned int cpu) +{ + struct thread_info *ti; + struct create_idle c_idle = { + .cpu = cpu, + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), + }; + INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle); + + c_idle.idle = get_idle_for_cpu(cpu); + + /* We can't use kernel_thread since we must avoid to + * reschedule the child. We use a workqueue because + * we want to fork from a kernel thread, not whatever + * userspace process happens to be trying to online us. + */ + if (!c_idle.idle) { + schedule_work(&c_idle.work); + wait_for_completion(&c_idle.done); + } else + init_idle(c_idle.idle, cpu); + if (IS_ERR(c_idle.idle)) { + pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle)); + return PTR_ERR(c_idle.idle); + } + ti = task_thread_info(c_idle.idle); + +#ifdef CONFIG_PPC64 + paca[cpu].__current = c_idle.idle; + paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD; +#endif + ti->cpu = cpu; + current_set[cpu] = ti; - return -ENOSYS; + return 0; } int __cpuinit __cpu_up(unsigned int cpu) { - int c; + int rc, c; secondary_ti = current_set[cpu]; - if (!cpu_enable(cpu)) - return 0; if (smp_ops == NULL || (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu))) return -EINVAL; + /* Make sure we have an idle thread */ + rc = create_idle(cpu); + if (rc) + return rc; + /* Make sure callin-map entry is 0 (can be leftover a CPU * hotplug */ @@ -502,7 +530,7 @@ static struct device_node *cpu_to_l2cache(int cpu) } /* Activate a secondary processor. */ -int __devinit start_secondary(void *unused) +void __devinit start_secondary(void *unused) { unsigned int cpu = smp_processor_id(); struct device_node *l2_cache; @@ -523,6 +551,10 @@ int __devinit start_secondary(void *unused) secondary_cpu_time_init(); +#ifdef CONFIG_PPC64 + if (system_state == SYSTEM_RUNNING) + vdso_data->processorCount++; +#endif ipi_call_lock(); notify_cpu_starting(cpu); set_cpu_online(cpu, true); @@ -558,7 +590,8 @@ int __devinit start_secondary(void *unused) local_irq_enable(); cpu_idle(); - return 0; + + BUG(); } int setup_profiling_timer(unsigned int multiplier) @@ -585,7 +618,11 @@ void __init smp_cpus_done(unsigned int max_cpus) free_cpumask_var(old_mask); + if (smp_ops && smp_ops->bringup_done) + smp_ops->bringup_done(); + dump_numa_cpu_topology(); + } int arch_sd_sibling_asym_packing(void) @@ -660,5 +697,9 @@ void cpu_die(void) { if (ppc_md.cpu_die) ppc_md.cpu_die(); + + /* If we return, we re-enter start_secondary */ + start_secondary_resume(); } + #endif diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 09d31dbf43f9..375480c56eb9 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -356,7 +356,7 @@ void account_system_vtime(struct task_struct *tsk) } get_paca()->user_time_scaled += user_scaled; - if (in_irq() || idle_task(smp_processor_id()) != tsk) { + if (in_interrupt() || idle_task(smp_processor_id()) != tsk) { account_system_time(tsk, 0, delta, sys_scaled); if (stolen) account_steal_time(stolen); @@ -577,14 +577,21 @@ void timer_interrupt(struct pt_regs * regs) struct clock_event_device *evt = &decrementer->event; u64 now; + /* Ensure a positive value is written to the decrementer, or else + * some CPUs will continue to take decrementer exceptions. + */ + set_dec(DECREMENTER_MAX); + + /* Some implementations of hotplug will get timer interrupts while + * offline, just ignore these + */ + if (!cpu_online(smp_processor_id())) + return; + trace_timer_interrupt_entry(regs); __get_cpu_var(irq_stat).timer_irqs++; - /* Ensure a positive value is written to the decrementer, or else - * some CPUs will continuue to take decrementer exceptions */ - set_dec(DECREMENTER_MAX); - #if defined(CONFIG_PPC32) && defined(CONFIG_PMAC) if (atomic_read(&ppc_n_lost_interrupts) != 0) do_IRQ(regs); diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c index 757c0bed9a91..b42f76c4948d 100644 --- a/arch/powerpc/mm/dma-noncoherent.c +++ b/arch/powerpc/mm/dma-noncoherent.c @@ -399,3 +399,23 @@ void __dma_sync_page(struct page *page, unsigned long offset, #endif } EXPORT_SYMBOL(__dma_sync_page); + +/* + * Return the PFN for a given cpu virtual address returned by + * __dma_alloc_coherent. This is used by dma_mmap_coherent() + */ +unsigned long __dma_get_coherent_pfn(unsigned long cpu_addr) +{ + /* This should always be populated, so we don't test every + * level. If that fails, we'll have a nice crash which + * will be as good as a BUG_ON() + */ + pgd_t *pgd = pgd_offset_k(cpu_addr); + pud_t *pud = pud_offset(pgd, cpu_addr); + pmd_t *pmd = pmd_offset(pud, cpu_addr); + pte_t *ptep = pte_offset_kernel(pmd, cpu_addr); + + if (pte_none(*ptep) || !pte_present(*ptep)) + return 0; + return pte_pfn(*ptep); +} diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S index 8526bd9d2aa3..222815112e45 100644 --- a/arch/powerpc/mm/tlb_low_64e.S +++ b/arch/powerpc/mm/tlb_low_64e.S @@ -431,7 +431,7 @@ virt_page_table_tlb_miss_fault: * The thing is, we know that in normal circumstances, this is * always called as a second level tlb miss for SW load or as a first * level TLB miss for HW load, so we should be able to peek at the - * relevant informations in the first exception frame in the PACA. + * relevant information in the first exception frame in the PACA. * * However, we do need to double check that, because we may just hit * a stray kernel pointer or a userland attack trying to hit those diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index 20576829eca5..f7b07720aa30 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -46,7 +46,7 @@ config PPC_OF_BOOT_TRAMPOLINE help Support from booting from Open Firmware or yaboot using an Open Firmware client interface. This enables the kernel to - communicate with open firmware to retrieve system informations + communicate with open firmware to retrieve system information such as the device tree. In case of doubt, say Y diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index a19bec078703..44cfd1bef89b 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -244,7 +244,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq, break; case IIC_IRQ_TYPE_IOEXC: irq_set_chip_and_handler(virq, &iic_ioexc_chip, - handle_iic_irq); + handle_edge_eoi_irq); break; default: irq_set_chip_and_handler(virq, &iic_chip, handle_edge_eoi_irq); diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index f0bc08f6c1f0..20468f49aec0 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -33,7 +33,6 @@ extern void pmac_setup_pci_dma(void); extern void pmac_check_ht_link(void); extern void pmac_setup_smp(void); -extern void pmac32_cpu_die(void); extern void low_cpu_die(void) __attribute__((noreturn)); extern int pmac_nvram_init(void); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index d5aceb7fb125..aa45281bd296 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -650,51 +650,6 @@ static int pmac_pci_probe_mode(struct pci_bus *bus) return PCI_PROBE_NORMAL; return PCI_PROBE_DEVTREE; } - -#ifdef CONFIG_HOTPLUG_CPU -/* access per cpu vars from generic smp.c */ -DECLARE_PER_CPU(int, cpu_state); - -static void pmac64_cpu_die(void) -{ - /* - * turn off as much as possible, we'll be - * kicked out as this will only be invoked - * on core99 platforms for now ... - */ - - printk(KERN_INFO "CPU#%d offline\n", smp_processor_id()); - __get_cpu_var(cpu_state) = CPU_DEAD; - smp_wmb(); - - /* - * during the path that leads here preemption is disabled, - * reenable it now so that when coming up preempt count is - * zero correctly - */ - preempt_enable(); - - /* - * hard-disable interrupts for the non-NAP case, the NAP code - * needs to re-enable interrupts (but soft-disables them) - */ - hard_irq_disable(); - - while (1) { - /* let's not take timer interrupts too often ... */ - set_dec(0x7fffffff); - - /* should always be true at this point */ - if (cpu_has_feature(CPU_FTR_CAN_NAP)) - power4_cpu_offline_powersave(); - else { - HMT_low(); - HMT_very_low(); - } - } -} -#endif /* CONFIG_HOTPLUG_CPU */ - #endif /* CONFIG_PPC64 */ define_machine(powermac) { @@ -726,15 +681,4 @@ define_machine(powermac) { .pcibios_after_init = pmac_pcibios_after_init, .phys_mem_access_prot = pci_phys_mem_access_prot, #endif -#ifdef CONFIG_HOTPLUG_CPU -#ifdef CONFIG_PPC64 - .cpu_die = pmac64_cpu_die, -#endif -#ifdef CONFIG_PPC32 - .cpu_die = pmac32_cpu_die, -#endif -#endif -#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) - .cpu_die = generic_mach_cpu_die, -#endif }; diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index c95215f4f8b6..a830c5e80657 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c @@ -840,92 +840,149 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr) /* Setup openpic */ mpic_setup_this_cpu(); +} - if (cpu_nr == 0) { -#ifdef CONFIG_PPC64 - extern void g5_phy_disable_cpu1(void); +#ifdef CONFIG_HOTPLUG_CPU +static int smp_core99_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + int rc; - /* Close i2c bus if it was used for tb sync */ + switch(action) { + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + /* Open i2c bus if it was used for tb sync */ if (pmac_tb_clock_chip_host) { - pmac_i2c_close(pmac_tb_clock_chip_host); - pmac_tb_clock_chip_host = NULL; + rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1); + if (rc) { + pr_err("Failed to open i2c bus for time sync\n"); + return notifier_from_errno(rc); + } } + break; + case CPU_ONLINE: + case CPU_UP_CANCELED: + /* Close i2c bus if it was used for tb sync */ + if (pmac_tb_clock_chip_host) + pmac_i2c_close(pmac_tb_clock_chip_host); + break; + default: + break; + } + return NOTIFY_OK; +} - /* If we didn't start the second CPU, we must take - * it off the bus - */ - if (of_machine_is_compatible("MacRISC4") && - num_online_cpus() < 2) - g5_phy_disable_cpu1(); -#endif /* CONFIG_PPC64 */ +static struct notifier_block __cpuinitdata smp_core99_cpu_nb = { + .notifier_call = smp_core99_cpu_notify, +}; +#endif /* CONFIG_HOTPLUG_CPU */ + +static void __init smp_core99_bringup_done(void) +{ +#ifdef CONFIG_PPC64 + extern void g5_phy_disable_cpu1(void); + + /* Close i2c bus if it was used for tb sync */ + if (pmac_tb_clock_chip_host) + pmac_i2c_close(pmac_tb_clock_chip_host); - if (ppc_md.progress) - ppc_md.progress("core99_setup_cpu 0 done", 0x349); + /* If we didn't start the second CPU, we must take + * it off the bus. + */ + if (of_machine_is_compatible("MacRISC4") && + num_online_cpus() < 2) { + set_cpu_present(1, false); + g5_phy_disable_cpu1(); } -} +#endif /* CONFIG_PPC64 */ +#ifdef CONFIG_HOTPLUG_CPU + register_cpu_notifier(&smp_core99_cpu_nb); +#endif + if (ppc_md.progress) + ppc_md.progress("smp_core99_bringup_done", 0x349); +} -#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) +#ifdef CONFIG_HOTPLUG_CPU -int smp_core99_cpu_disable(void) +static int smp_core99_cpu_disable(void) { - set_cpu_online(smp_processor_id(), false); + int rc = generic_cpu_disable(); + if (rc) + return rc; - /* XXX reset cpu affinity here */ mpic_cpu_set_priority(0xf); - asm volatile("mtdec %0" : : "r" (0x7fffffff)); - mb(); - udelay(20); - asm volatile("mtdec %0" : : "r" (0x7fffffff)); + return 0; } -static int cpu_dead[NR_CPUS]; +#ifdef CONFIG_PPC32 -void pmac32_cpu_die(void) +static void pmac_cpu_die(void) { + int cpu = smp_processor_id(); + local_irq_disable(); - cpu_dead[smp_processor_id()] = 1; + idle_task_exit(); + pr_debug("CPU%d offline\n", cpu); + generic_set_cpu_dead(cpu); + smp_wmb(); mb(); low_cpu_die(); } -void smp_core99_cpu_die(unsigned int cpu) +#else /* CONFIG_PPC32 */ + +static void pmac_cpu_die(void) { - int timeout; + int cpu = smp_processor_id(); - timeout = 1000; - while (!cpu_dead[cpu]) { - if (--timeout == 0) { - printk("CPU %u refused to die!\n", cpu); - break; - } - msleep(1); + local_irq_disable(); + idle_task_exit(); + + /* + * turn off as much as possible, we'll be + * kicked out as this will only be invoked + * on core99 platforms for now ... + */ + + printk(KERN_INFO "CPU#%d offline\n", cpu); + generic_set_cpu_dead(cpu); + smp_wmb(); + + /* + * Re-enable interrupts. The NAP code needs to enable them + * anyways, do it now so we deal with the case where one already + * happened while soft-disabled. + * We shouldn't get any external interrupts, only decrementer, and the + * decrementer handler is safe for use on offline CPUs + */ + local_irq_enable(); + + while (1) { + /* let's not take timer interrupts too often ... */ + set_dec(0x7fffffff); + + /* Enter NAP mode */ + power4_idle(); } - cpu_dead[cpu] = 0; } -#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */ +#endif /* else CONFIG_PPC32 */ +#endif /* CONFIG_HOTPLUG_CPU */ /* Core99 Macs (dual G4s and G5s) */ struct smp_ops_t core99_smp_ops = { .message_pass = smp_mpic_message_pass, .probe = smp_core99_probe, + .bringup_done = smp_core99_bringup_done, .kick_cpu = smp_core99_kick_cpu, .setup_cpu = smp_core99_setup_cpu, .give_timebase = smp_core99_give_timebase, .take_timebase = smp_core99_take_timebase, #if defined(CONFIG_HOTPLUG_CPU) -# if defined(CONFIG_PPC32) .cpu_disable = smp_core99_cpu_disable, - .cpu_die = smp_core99_cpu_die, -# endif -# if defined(CONFIG_PPC64) - .cpu_disable = generic_cpu_disable, .cpu_die = generic_cpu_die, - /* intentionally do *NOT* assign cpu_enable, - * the generic code will use kick_cpu then! */ -# endif #endif }; @@ -957,5 +1014,10 @@ void __init pmac_setup_smp(void) smp_ops = &psurge_smp_ops; } #endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_HOTPLUG_CPU + ppc_md.cpu_die = pmac_cpu_die; +#endif } + diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 419707b07248..00cc3a094885 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -480,8 +480,32 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, const char *new_msgs, unsigned long new_len) { static unsigned int oops_count = 0; + static bool panicking = false; size_t text_len; + switch (reason) { + case KMSG_DUMP_RESTART: + case KMSG_DUMP_HALT: + case KMSG_DUMP_POWEROFF: + /* These are almost always orderly shutdowns. */ + return; + case KMSG_DUMP_OOPS: + case KMSG_DUMP_KEXEC: + break; + case KMSG_DUMP_PANIC: + panicking = true; + break; + case KMSG_DUMP_EMERG: + if (panicking) + /* Panic report already captured. */ + return; + break; + default: + pr_err("%s: ignoring unrecognized KMSG_DUMP_* reason %d\n", + __FUNCTION__, (int) reason); + return; + } + if (clobbering_unread_rtas_event()) return; diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h index 75a6f480d931..08672d9136ab 100644 --- a/arch/powerpc/platforms/pseries/offline_states.h +++ b/arch/powerpc/platforms/pseries/offline_states.h @@ -34,6 +34,4 @@ static inline void set_default_offline_state(int cpu) #endif extern enum cpu_state_vals get_preferred_offline_state(int cpu); -extern int start_secondary(void); -extern void start_secondary_resume(void); #endif diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index c319d04aa799..000724149089 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -378,7 +378,7 @@ static int __init pSeries_init_panel(void) return 0; } -arch_initcall(pSeries_init_panel); +machine_arch_initcall(pseries, pSeries_init_panel); static int pseries_set_dabr(unsigned long dabr) { diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 0317cce877c6..a509c5292a67 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -64,8 +64,8 @@ int smp_query_cpu_stopped(unsigned int pcpu) int qcss_tok = rtas_token("query-cpu-stopped-state"); if (qcss_tok == RTAS_UNKNOWN_SERVICE) { - printk(KERN_INFO "Firmware doesn't support " - "query-cpu-stopped-state\n"); + printk_once(KERN_INFO + "Firmware doesn't support query-cpu-stopped-state\n"); return QCSS_HARDWARE_ERROR; } @@ -112,10 +112,10 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) /* Fixup atomic count: it exited inside IRQ handler. */ task_thread_info(paca[lcpu].__current)->preempt_count = 0; - +#ifdef CONFIG_HOTPLUG_CPU if (get_cpu_current_state(lcpu) == CPU_STATE_INACTIVE) goto out; - +#endif /* * If the RTAS start-cpu token does not exist then presume the * cpu is already spinning. @@ -130,7 +130,9 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu) return 0; } +#ifdef CONFIG_HOTPLUG_CPU out: +#endif return 1; } @@ -144,16 +146,15 @@ static void __devinit smp_xics_setup_cpu(int cpu) vpa_init(cpu); cpumask_clear_cpu(cpu, of_spin_mask); +#ifdef CONFIG_HOTPLUG_CPU set_cpu_current_state(cpu, CPU_STATE_ONLINE); set_default_offline_state(cpu); - +#endif } #endif /* CONFIG_XICS */ static void __devinit smp_pSeries_kick_cpu(int nr) { - long rc; - unsigned long hcpuid; BUG_ON(nr < 0 || nr >= NR_CPUS); if (!smp_startup_cpu(nr)) @@ -165,16 +166,20 @@ static void __devinit smp_pSeries_kick_cpu(int nr) * the processor will continue on to secondary_start */ paca[nr].cpu_start = 1; - +#ifdef CONFIG_HOTPLUG_CPU set_preferred_offline_state(nr, CPU_STATE_ONLINE); if (get_cpu_current_state(nr) == CPU_STATE_INACTIVE) { + long rc; + unsigned long hcpuid; + hcpuid = get_hard_smp_processor_id(nr); rc = plpar_hcall_norets(H_PROD, hcpuid); if (rc != H_SUCCESS) printk(KERN_ERR "Error: Prod to wake up processor %d " "Ret= %ld\n", nr, rc); } +#endif } static int smp_pSeries_cpu_bootable(unsigned int nr) diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 6c1e638f0ce9..ec8fe22047b7 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -204,33 +204,33 @@ static int get_irq_server(unsigned int virq, const struct cpumask *cpumask, static void xics_unmask_irq(struct irq_data *d) { - unsigned int irq; + unsigned int hwirq; int call_status; int server; pr_devel("xics: unmask virq %d\n", d->irq); - irq = (unsigned int)irq_map[d->irq].hwirq; - pr_devel(" -> map to hwirq 0x%x\n", irq); - if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) + hwirq = (unsigned int)irq_map[d->irq].hwirq; + pr_devel(" -> map to hwirq 0x%x\n", hwirq); + if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS) return; server = get_irq_server(d->irq, d->affinity, 0); - call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, + call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq, server, DEFAULT_PRIORITY); if (call_status != 0) { printk(KERN_ERR "%s: ibm_set_xive irq %u server %x returned %d\n", - __func__, irq, server, call_status); + __func__, hwirq, server, call_status); return; } /* Now unmask the interrupt (often a no-op) */ - call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq); + call_status = rtas_call(ibm_int_on, 1, 1, NULL, hwirq); if (call_status != 0) { printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n", - __func__, irq, call_status); + __func__, hwirq, call_status); return; } } @@ -250,46 +250,46 @@ static unsigned int xics_startup(struct irq_data *d) return 0; } -static void xics_mask_real_irq(struct irq_data *d) +static void xics_mask_real_irq(unsigned int hwirq) { int call_status; - if (d->irq == XICS_IPI) + if (hwirq == XICS_IPI) return; - call_status = rtas_call(ibm_int_off, 1, 1, NULL, d->irq); + call_status = rtas_call(ibm_int_off, 1, 1, NULL, hwirq); if (call_status != 0) { printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n", - __func__, d->irq, call_status); + __func__, hwirq, call_status); return; } /* Have to set XIVE to 0xff to be able to remove a slot */ - call_status = rtas_call(ibm_set_xive, 3, 1, NULL, d->irq, + call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq, default_server, 0xff); if (call_status != 0) { printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n", - __func__, d->irq, call_status); + __func__, hwirq, call_status); return; } } static void xics_mask_irq(struct irq_data *d) { - unsigned int irq; + unsigned int hwirq; pr_devel("xics: mask virq %d\n", d->irq); - irq = (unsigned int)irq_map[d->irq].hwirq; - if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) + hwirq = (unsigned int)irq_map[d->irq].hwirq; + if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS) return; - xics_mask_real_irq(d); + xics_mask_real_irq(hwirq); } static void xics_mask_unknown_vec(unsigned int vec) { printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec); - xics_mask_real_irq(irq_get_irq_data(vec)); + xics_mask_real_irq(vec); } static inline unsigned int xics_xirr_vector(unsigned int xirr) @@ -373,37 +373,37 @@ static unsigned char pop_cppr(void) static void xics_eoi_direct(struct irq_data *d) { - unsigned int irq = (unsigned int)irq_map[d->irq].hwirq; + unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq; iosync(); - direct_xirr_info_set((pop_cppr() << 24) | irq); + direct_xirr_info_set((pop_cppr() << 24) | hwirq); } static void xics_eoi_lpar(struct irq_data *d) { - unsigned int irq = (unsigned int)irq_map[d->irq].hwirq; + unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq; iosync(); - lpar_xirr_info_set((pop_cppr() << 24) | irq); + lpar_xirr_info_set((pop_cppr() << 24) | hwirq); } static int xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force) { - unsigned int irq; + unsigned int hwirq; int status; int xics_status[2]; int irq_server; - irq = (unsigned int)irq_map[d->irq].hwirq; - if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) + hwirq = (unsigned int)irq_map[d->irq].hwirq; + if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS) return -1; - status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); + status = rtas_call(ibm_get_xive, 1, 3, xics_status, hwirq); if (status) { printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n", - __func__, irq, status); + __func__, hwirq, status); return -1; } @@ -418,11 +418,11 @@ xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force) } status = rtas_call(ibm_set_xive, 3, 1, NULL, - irq, irq_server, xics_status[1]); + hwirq, irq_server, xics_status[1]); if (status) { printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n", - __func__, irq, status); + __func__, hwirq, status); return -1; } @@ -874,7 +874,7 @@ void xics_kexec_teardown_cpu(int secondary) void xics_migrate_irqs_away(void) { int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); - unsigned int irq, virq; + int virq; /* If we used to be the default server, move to the new "boot_cpuid" */ if (hw_cpu == default_server) @@ -892,6 +892,7 @@ void xics_migrate_irqs_away(void) for_each_irq(virq) { struct irq_desc *desc; struct irq_chip *chip; + unsigned int hwirq; int xics_status[2]; int status; unsigned long flags; @@ -901,9 +902,9 @@ void xics_migrate_irqs_away(void) continue; if (irq_map[virq].host != xics_host) continue; - irq = (unsigned int)irq_map[virq].hwirq; + hwirq = (unsigned int)irq_map[virq].hwirq; /* We need to get IPIs still. */ - if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) + if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS) continue; desc = irq_to_desc(virq); @@ -918,10 +919,10 @@ void xics_migrate_irqs_away(void) raw_spin_lock_irqsave(&desc->lock, flags); - status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); + status = rtas_call(ibm_get_xive, 1, 3, xics_status, hwirq); if (status) { printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n", - __func__, irq, status); + __func__, hwirq, status); goto unlock; } diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c index f550e23632f8..a88800ff4d01 100644 --- a/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/arch/powerpc/sysdev/mpc8xx_pic.c @@ -80,7 +80,7 @@ static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) if ((hw & 1) == 0) { siel |= (0x80000000 >> hw); out_be32(&siu_reg->sc_siel, siel); - __irq_set_handler_locked(irq, handle_edge_irq); + __irq_set_handler_locked(d->irq, handle_edge_irq); } } return 0; diff --git a/arch/score/Kconfig b/arch/score/Kconfig index 4278bbc032ce..e73bc781cc14 100644 --- a/arch/score/Kconfig +++ b/arch/score/Kconfig @@ -3,7 +3,6 @@ menu "Machine selection" config SCORE def_bool y select HAVE_GENERIC_HARDIRQS - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW choice diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 9af3c8d0776b..bc439de48cd1 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -23,7 +23,6 @@ config SUPERH select HAVE_SPARSE_IRQ select RTC_LIB select GENERIC_ATOMIC64 - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW help The SuperH is a RISC processor targeted for use in embedded systems diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 14b234631f5f..e560d102215a 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -51,7 +51,6 @@ config SPARC64 select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select HAVE_GENERIC_HARDIRQS - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW select IRQ_PREFLOW_FASTEOI diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h index 2f475d7c0b53..9d897b6db983 100644 --- a/arch/sparc/include/asm/unistd.h +++ b/arch/sparc/include/asm/unistd.h @@ -403,8 +403,9 @@ #define __NR_name_to_handle_at 332 #define __NR_open_by_handle_at 333 #define __NR_clock_adjtime 334 +#define __NR_syncfs 335 -#define NR_syscalls 335 +#define NR_syscalls 336 #ifdef __32bit_syscall_numbers__ /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c index 2abace076c7d..773091ac71a3 100644 --- a/arch/sparc/kernel/auxio_64.c +++ b/arch/sparc/kernel/auxio_64.c @@ -93,7 +93,7 @@ void auxio_set_lte(int on) } EXPORT_SYMBOL(auxio_set_lte); -static struct of_device_id __initdata auxio_match[] = { +static const struct of_device_id auxio_match[] = { { .name = "auxio", }, diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index 136d3718a74a..7eef3f741963 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -140,7 +140,7 @@ out_free: goto out; } -static struct of_device_id __initdata clock_board_match[] = { +static const struct of_device_id clock_board_match[] = { { .name = "clock-board", }, @@ -245,7 +245,7 @@ out_free: goto out; } -static struct of_device_id __initdata fhc_match[] = { +static const struct of_device_id fhc_match[] = { { .name = "fhc", }, diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index 4a700f4b79ce..3add4de8a1a9 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -1218,7 +1218,7 @@ static int ds_remove(struct vio_dev *vdev) return 0; } -static struct vio_device_id __initdata ds_match[] = { +static const struct vio_device_id ds_match[] = { { .type = "domain-services-port", }, diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 1504df8ddf70..906ee3e24cc9 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1283,7 +1283,7 @@ linux_syscall_trace: .globl ret_from_fork ret_from_fork: call schedule_tail - mov %g3, %o0 + ld [%g3 + TI_TASK], %o0 b ret_sys_call ld [%sp + STACKFRAME_SZ + PT_I0], %o0 diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 6addb914fcc8..56db06432ce9 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -107,7 +107,7 @@ static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size return hp; } -static void mdesc_memblock_free(struct mdesc_handle *hp) +static void __init mdesc_memblock_free(struct mdesc_handle *hp) { unsigned int alloc_size; unsigned long start; diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 3d70f8326efd..d29a32fcc5e4 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -496,7 +496,7 @@ out_err: return err; } -static struct of_device_id __initdata fire_match[] = { +static const struct of_device_id fire_match[] = { { .name = "pci", .compatible = "pciex108e,80f0", diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 56ee745064de..86ae08d9b6ee 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -592,7 +592,7 @@ out_err: return err; } -static struct of_device_id __initdata psycho_match[] = { +static const struct of_device_id psycho_match[] = { { .name = "pci", .compatible = "pci108e,8000", diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index 2857073342d2..948068a083fc 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -581,7 +581,7 @@ out_err: return err; } -static struct of_device_id __initdata sabre_match[] = { +static const struct of_device_id sabre_match[] = { { .name = "pci", .compatible = "pci108e,a001", diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 1d41af73a92f..fecfcb2063c8 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1470,7 +1470,7 @@ static int __devinit schizo_probe(struct platform_device *op) * and pci108e,8001. So list the chips in reverse chronological * order. */ -static struct of_device_id __initdata schizo_match[] = { +static const struct of_device_id schizo_match[] = { { .name = "pci", .compatible = "pci108e,a801", diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 6cf534681788..b01a06e9ae4e 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -998,7 +998,7 @@ out_err: return err; } -static struct of_device_id __initdata pci_sun4v_match[] = { +static const struct of_device_id pci_sun4v_match[] = { { .name = "pci", .compatible = "SUNW,sun4v-pci", diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c index cd725fe238b2..cb4c0f57c024 100644 --- a/arch/sparc/kernel/power.c +++ b/arch/sparc/kernel/power.c @@ -52,7 +52,7 @@ static int __devinit power_probe(struct platform_device *op) return 0; } -static struct of_device_id __initdata power_match[] = { +static const struct of_device_id power_match[] = { { .name = "power", }, diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 4b86eaf04fe5..47ac73c32e88 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -84,4 +84,4 @@ sys_call_table: /*320*/ .long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv /*325*/ .long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime - +/*335*/ .long sys_syncfs diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 0331bafdf3a3..4f3170c1ef47 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -85,6 +85,7 @@ sys_call_table32: /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv .word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init /*330*/ .word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime + .word sys_syncfs #endif /* CONFIG_COMPAT */ @@ -161,3 +162,4 @@ sys_call_table: /*320*/ .word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv .word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime + .word sys_syncfs diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index 95ec25faba39..2b8d54b2d850 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -442,7 +442,7 @@ static int __devinit rtc_probe(struct platform_device *op) return platform_device_register(&rtc_cmos_device); } -static struct of_device_id __initdata rtc_match[] = { +static const struct of_device_id rtc_match[] = { { .name = "rtc", .compatible = "m5819", @@ -487,7 +487,7 @@ static int __devinit bq4802_probe(struct platform_device *op) return platform_device_register(&rtc_bq4802_device); } -static struct of_device_id __initdata bq4802_match[] = { +static const struct of_device_id bq4802_match[] = { { .name = "rtc", .compatible = "bq4802", @@ -552,7 +552,7 @@ static int __devinit mostek_probe(struct platform_device *op) return platform_device_register(&m48t59_rtc); } -static struct of_device_id __initdata mostek_match[] = { +static const struct of_device_id mostek_match[] = { { .name = "eeprom", }, diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 5e34a9fee9b3..6e2cdd5ae96b 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig @@ -11,7 +11,6 @@ config TILE select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select GENERIC_PENDING_IRQ if SMP - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW # FIXME: investigate whether we need/want these options. diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index 109ddc0071c6..a9234838e8a2 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -7,7 +7,6 @@ config UML bool default y select HAVE_GENERIC_HARDIRQS - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW config MMU diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig index 04e024919b2b..d3a303246c9f 100644 --- a/arch/unicore32/Kconfig +++ b/arch/unicore32/Kconfig @@ -10,7 +10,6 @@ config UNICORE32 select HAVE_KERNEL_LZMA select GENERIC_FIND_FIRST_BIT select GENERIC_IRQ_PROBE - select GENERIC_HARDIRQS_NO_DEPRECATED select GENERIC_IRQ_SHOW select ARCH_WANT_FRAME_POINTERS help diff --git a/arch/unicore32/Makefile b/arch/unicore32/Makefile index e08d6d370a8a..76a8beec7d03 100644 --- a/arch/unicore32/Makefile +++ b/arch/unicore32/Makefile @@ -48,7 +48,7 @@ ASM_GENERIC_HEADERS += bitsperlong.h bug.h bugs.h ASM_GENERIC_HEADERS += cputime.h current.h ASM_GENERIC_HEADERS += device.h div64.h ASM_GENERIC_HEADERS += emergency-restart.h errno.h -ASM_GENERIC_HEADERS += fb.h fcntl.h ftrace.h +ASM_GENERIC_HEADERS += fb.h fcntl.h ftrace.h futex.h ASM_GENERIC_HEADERS += hardirq.h hw_irq.h ASM_GENERIC_HEADERS += ioctl.h ioctls.h ipcbuf.h irq_regs.h ASM_GENERIC_HEADERS += kdebug.h kmap_types.h diff --git a/arch/unicore32/include/asm/futex.h b/arch/unicore32/include/asm/futex.h deleted file mode 100644 index 07dea6170558..000000000000 --- a/arch/unicore32/include/asm/futex.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * linux/arch/unicore32/include/asm/futex.h - * - * Code specific to PKUnity SoC and UniCore ISA - * - * Copyright (C) 2001-2010 GUAN Xue-tao - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __UNICORE_FUTEX_H__ -#define __UNICORE_FUTEX_H__ - -#ifdef __KERNEL__ - -#include <linux/futex.h> -#include <linux/preempt.h> -#include <linux/uaccess.h> -#include <linux/errno.h> - -#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ - __asm__ __volatile__( \ - "1: ldw.u %1, [%2]\n" \ - " " insn "\n" \ - "2: stw.u %0, [%2]\n" \ - " mov %0, #0\n" \ - "3:\n" \ - " .pushsection __ex_table,\"a\"\n" \ - " .align 3\n" \ - " .long 1b, 4f, 2b, 4f\n" \ - " .popsection\n" \ - " .pushsection .fixup,\"ax\"\n" \ - "4: mov %0, %4\n" \ - " b 3b\n" \ - " .popsection" \ - : "=&r" (ret), "=&r" (oldval) \ - : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \ - : "cc", "memory") - -static inline int -futex_atomic_op_inuser(int encoded_op, int __user *uaddr) -{ - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; - int oldval = 0, ret; - - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - - pagefault_disable(); /* implies preempt_disable() */ - - switch (op) { - case FUTEX_OP_SET: - __futex_atomic_op("mov %0, %3", ret, oldval, uaddr, oparg); - break; - case FUTEX_OP_ADD: - __futex_atomic_op("add %0, %1, %3", ret, oldval, uaddr, oparg); - break; - case FUTEX_OP_OR: - __futex_atomic_op("or %0, %1, %3", ret, oldval, uaddr, oparg); - break; - case FUTEX_OP_ANDN: - __futex_atomic_op("and %0, %1, %3", - ret, oldval, uaddr, ~oparg); - break; - case FUTEX_OP_XOR: - __futex_atomic_op("xor %0, %1, %3", ret, oldval, uaddr, oparg); - break; - default: - ret = -ENOSYS; - } - - pagefault_enable(); /* subsumes preempt_enable() */ - - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } - return ret; -} - -static inline int -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) -{ - int val; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - - pagefault_disable(); /* implies preempt_disable() */ - - __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" - "1: ldw.u %0, [%3]\n" - " cmpxor.a %0, %1\n" - " bne 3f\n" - "2: stw.u %2, [%3]\n" - "3:\n" - " .pushsection __ex_table,\"a\"\n" - " .align 3\n" - " .long 1b, 4f, 2b, 4f\n" - " .popsection\n" - " .pushsection .fixup,\"ax\"\n" - "4: mov %0, %4\n" - " b 3b\n" - " .popsection" - : "=&r" (val) - : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) - : "cc", "memory"); - - pagefault_enable(); /* subsumes preempt_enable() */ - - return val; -} - -#endif /* __KERNEL__ */ -#endif /* __UNICORE_FUTEX_H__ */ diff --git a/arch/unicore32/include/mach/PKUnity.h b/arch/unicore32/include/mach/PKUnity.h index a18bdc3810e6..8040d575dddb 100644 --- a/arch/unicore32/include/mach/PKUnity.h +++ b/arch/unicore32/include/mach/PKUnity.h @@ -24,16 +24,6 @@ #define PKUNITY_MMIO_BASE 0x80000000 /* 0x80000000 - 0xFFFFFFFF 2GB */ /* - * PKUNITY Memory Map Addresses: 0x0D000000 - 0x0EFFFFFF (32MB) - * 0x0D000000 - 0x0DFFFFFF 16MB: for UVC - * 0x0E000000 - 0x0EFFFFFF 16MB: for UNIGFX - */ -#define PKUNITY_UVC_MMAP_BASE 0x0D000000 -#define PKUNITY_UVC_MMAP_SIZE 0x01000000 /* 16MB */ -#define PKUNITY_UNIGFX_MMAP_BASE 0x0E000000 -#define PKUNITY_UNIGFX_MMAP_SIZE 0x01000000 /* 16MB */ - -/* * PKUNITY System Bus Addresses (PCI): 0x80000000 - 0xBFFFFFFF (1GB) * 0x80000000 - 0x8000000B 12B PCI Configuration regs * 0x80010000 - 0x80010250 592B PCI Bridge Base diff --git a/arch/unicore32/include/mach/memory.h b/arch/unicore32/include/mach/memory.h index 0bf21c944710..4be72c21d491 100644 --- a/arch/unicore32/include/mach/memory.h +++ b/arch/unicore32/include/mach/memory.h @@ -50,7 +50,6 @@ void puv3_pci_adjust_zones(unsigned long *size, unsigned long *holes); /* kuser area */ #define KUSER_VECPAGE_BASE (KUSER_BASE + UL(0x3fff0000)) -#define KUSER_UNIGFX_BASE (PAGE_OFFSET + PKUNITY_UNIGFX_MMAP_BASE) /* kuser_vecpage (0xbfff0000) is ro, and vectors page (0xffff0000) is rw */ #define kuser_vecpage_to_vectors(x) ((x) - (KUSER_VECPAGE_BASE) \ + (VECTORS_BASE)) diff --git a/arch/unicore32/kernel/puv3-core.c b/arch/unicore32/kernel/puv3-core.c index 8b1b6beb858e..1a505a787765 100644 --- a/arch/unicore32/kernel/puv3-core.c +++ b/arch/unicore32/kernel/puv3-core.c @@ -99,11 +99,6 @@ static struct resource puv3_unigfx_resources[] = { .end = io_v2p(PKUNITY_UNIGFX_BASE) + 0xfff, .flags = IORESOURCE_MEM, }, - [1] = { - .start = PKUNITY_UNIGFX_MMAP_BASE, - .end = PKUNITY_UNIGFX_MMAP_BASE + PKUNITY_UNIGFX_MMAP_SIZE, - .flags = IORESOURCE_MEM, - }, }; static struct resource puv3_rtc_resources[] = { diff --git a/arch/unicore32/kernel/rtc.c b/arch/unicore32/kernel/rtc.c index c5f068295b51..8cad70b3302c 100644 --- a/arch/unicore32/kernel/rtc.c +++ b/arch/unicore32/kernel/rtc.c @@ -88,11 +88,6 @@ static int puv3_rtc_setpie(struct device *dev, int enabled) return 0; } -static int puv3_rtc_setfreq(struct device *dev, int freq) -{ - return 0; -} - /* Time read/write */ static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) @@ -214,8 +209,6 @@ static const struct rtc_class_ops puv3_rtcops = { .set_time = puv3_rtc_settime, .read_alarm = puv3_rtc_getalarm, .set_alarm = puv3_rtc_setalarm, - .irq_set_freq = puv3_rtc_setfreq, - .irq_set_state = puv3_rtc_setpie, .proc = puv3_rtc_proc, }; @@ -294,8 +287,6 @@ static int puv3_rtc_probe(struct platform_device *pdev) puv3_rtc_enable(pdev, 1); - puv3_rtc_setfreq(&pdev->dev, 1); - /* register RTC and exit */ rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops, diff --git a/arch/unicore32/kernel/setup.c b/arch/unicore32/kernel/setup.c index 1e175a82844d..471b6bca8da4 100644 --- a/arch/unicore32/kernel/setup.c +++ b/arch/unicore32/kernel/setup.c @@ -64,12 +64,6 @@ static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; */ static struct resource mem_res[] = { { - .name = "Video RAM", - .start = 0, - .end = 0, - .flags = IORESOURCE_MEM - }, - { .name = "Kernel text", .start = 0, .end = 0, @@ -83,9 +77,8 @@ static struct resource mem_res[] = { } }; -#define video_ram mem_res[0] -#define kernel_code mem_res[1] -#define kernel_data mem_res[2] +#define kernel_code mem_res[0] +#define kernel_data mem_res[1] /* * These functions re-use the assembly code in head.S, which @@ -224,10 +217,6 @@ request_standard_resources(struct meminfo *mi) kernel_data.end <= res->end) request_resource(res, &kernel_data); } - - video_ram.start = PKUNITY_UNIGFX_MMAP_BASE; - video_ram.end = PKUNITY_UNIGFX_MMAP_BASE + PKUNITY_UNIGFX_MMAP_SIZE; - request_resource(&iomem_resource, &video_ram); } static void (*init_machine)(void) __initdata; diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c index 25abbb101729..254e36fa9513 100644 --- a/arch/unicore32/kernel/traps.c +++ b/arch/unicore32/kernel/traps.c @@ -22,7 +22,6 @@ #include <linux/delay.h> #include <linux/hardirq.h> #include <linux/init.h> -#include <linux/uaccess.h> #include <linux/atomic.h> #include <linux/unistd.h> diff --git a/arch/unicore32/kernel/vmlinux.lds.S b/arch/unicore32/kernel/vmlinux.lds.S index 0b4eb89729e7..9bf7f7af52c5 100644 --- a/arch/unicore32/kernel/vmlinux.lds.S +++ b/arch/unicore32/kernel/vmlinux.lds.S @@ -14,6 +14,7 @@ #include <asm/thread_info.h> #include <asm/memory.h> #include <asm/page.h> +#include <asm/cache.h> OUTPUT_ARCH(unicore32) ENTRY(stext) @@ -29,7 +30,7 @@ SECTIONS HEAD_TEXT_SECTION INIT_TEXT_SECTION(PAGE_SIZE) INIT_DATA_SECTION(16) - PERCPU(PAGE_SIZE) + PERCPU(L1_CACHE_BYTES, PAGE_SIZE) __init_end = .; _stext = .; @@ -45,10 +46,10 @@ SECTIONS _sdata = .; RO_DATA_SECTION(PAGE_SIZE) - RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE) + RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) _edata = .; - EXCEPTION_TABLE(32) + EXCEPTION_TABLE(L1_CACHE_BYTES) NOTES BSS_SECTION(0, 0, 0) diff --git a/arch/unicore32/mm/mmu.c b/arch/unicore32/mm/mmu.c index 7bf3d588631f..db2d334941b4 100644 --- a/arch/unicore32/mm/mmu.c +++ b/arch/unicore32/mm/mmu.c @@ -338,15 +338,6 @@ void __init uc32_mm_memblock_reserve(void) * and can only be in node 0. */ memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t)); - -#ifdef CONFIG_PUV3_UNIGFX - /* - * These should likewise go elsewhere. They pre-reserve the - * screen/video memory region at the 48M~64M of main system memory. - */ - memblock_reserve(PKUNITY_UNIGFX_MMAP_BASE, PKUNITY_UNIGFX_MMAP_SIZE); - memblock_reserve(PKUNITY_UVC_MMAP_BASE, PKUNITY_UVC_MMAP_SIZE); -#endif } /* @@ -371,17 +362,6 @@ static void __init devicemaps_init(void) pmd_clear(pmd_off_k(addr)); /* - * Create a mapping for UniGFX VRAM - */ -#ifdef CONFIG_PUV3_UNIGFX - map.pfn = __phys_to_pfn(PKUNITY_UNIGFX_MMAP_BASE); - map.virtual = KUSER_UNIGFX_BASE; - map.length = PKUNITY_UNIGFX_MMAP_SIZE; - map.type = MT_KUSER; - create_mapping(&map); -#endif - - /* * Create a mapping for the machine vectors at the high-vectors * location (0xffff0000). If we aren't using high-vectors, also * create a mapping at the low-vectors virtual address. diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index a279d98ea95e..2b7d573be549 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -2,7 +2,6 @@ #define _ASM_X86_APIC_H #include <linux/cpumask.h> -#include <linux/delay.h> #include <linux/pm.h> #include <asm/alternative.h> diff --git a/arch/x86/include/asm/dma.h b/arch/x86/include/asm/dma.h index 97b6d8114a43..057099e5faba 100644 --- a/arch/x86/include/asm/dma.h +++ b/arch/x86/include/asm/dma.h @@ -10,7 +10,6 @@ #include <linux/spinlock.h> /* And spinlocks */ #include <asm/io.h> /* need byte IO */ -#include <linux/delay.h> #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER #define dma_outb outb_p diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 6801959a8b2a..4c39baa8facc 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -21,7 +21,7 @@ const struct pci_device_id amd_nb_misc_ids[] = { EXPORT_SYMBOL(amd_nb_misc_ids); static struct pci_device_id amd_nb_link_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_LINK) }, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, {} }; diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index 1293c709ee85..cd1ffed4ee22 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c @@ -316,7 +316,7 @@ static void apbt_setup_irq(struct apbt_dev *adev) irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT); irq_set_affinity(adev->irq, cpumask_of(adev->cpu)); /* APB timer irqs are set up as mp_irqs, timer is edge type */ - __set_irq_handler(adev->irq, handle_edge_irq, 0, "edge"); + __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge"); if (system_state == SYSTEM_BOOTING) { if (request_irq(adev->irq, apbt_interrupt_handler, diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index c4e557a1ebb6..5260fe91bcb6 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c @@ -16,6 +16,7 @@ #include <linux/kprobes.h> #include <linux/nmi.h> #include <linux/module.h> +#include <linux/delay.h> #ifdef CONFIG_HARDLOCKUP_DETECTOR u64 hw_nmi_get_sample_period(void) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 3c289281394c..33b10a0fc095 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -23,6 +23,8 @@ #include <linux/io.h> #include <linux/pci.h> #include <linux/kdebug.h> +#include <linux/delay.h> +#include <linux/crash_dump.h> #include <asm/uv/uv_mmrs.h> #include <asm/uv/uv_hub.h> @@ -34,6 +36,7 @@ #include <asm/ipi.h> #include <asm/smp.h> #include <asm/x86_init.h> +#include <asm/emergency-restart.h> DEFINE_PER_CPU(int, x2apic_extra_bits); @@ -810,4 +813,11 @@ void __init uv_system_init(void) /* register Legacy VGA I/O redirection handler */ pci_register_set_vga_state(uv_set_vga_state); + + /* + * For a kdump kernel the reset must be BOOT_ACPI, not BOOT_EFI, as + * EFI is not enabled in the kdump kernel. + */ + if (is_kdump_kernel()) + reboot_type = BOOT_ACPI; } diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 5a05ef63eb4a..3385ea26f684 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1626,7 +1626,7 @@ out: static unsigned int mce_poll(struct file *file, poll_table *wait) { poll_wait(file, &mce_wait, wait); - if (rcu_dereference_check_mce(mcelog.next)) + if (rcu_access_index(mcelog.next)) return POLLIN | POLLRDNORM; if (!mce_apei_read_done && apei_check_mce()) return POLLIN | POLLRDNORM; diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index 307dfbbf4a8e..929739a653d1 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -293,14 +293,24 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ /* * HACK! - * We use this same function to initialize the mtrrs on boot. - * The state of the boot cpu's mtrrs has been saved, and we want - * to replicate across all the APs. - * If we're doing that @reg is set to something special... + * + * We use this same function to initialize the mtrrs during boot, + * resume, runtime cpu online and on an explicit request to set a + * specific MTRR. + * + * During boot or suspend, the state of the boot cpu's mtrrs has been + * saved, and we want to replicate that across all the cpus that come + * online (either at the end of boot or resume or during a runtime cpu + * online). If we're doing that, @reg is set to something special and on + * this cpu we still do mtrr_if->set_all(). During boot/resume, this + * is unnecessary if at this point we are still on the cpu that started + * the boot/resume sequence. But there is no guarantee that we are still + * on the same cpu. So we do mtrr_if->set_all() on this cpu aswell to be + * sure that we are in sync with everyone else. */ if (reg != ~0U) mtrr_if->set(reg, base, size, type); - else if (!mtrr_aps_delayed_init) + else mtrr_if->set_all(); /* Wait for the others */ diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 948a31eae75f..1cb0b9fc78dc 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -8,6 +8,7 @@ #include <linux/seq_file.h> #include <linux/smp.h> #include <linux/ftrace.h> +#include <linux/delay.h> #include <asm/apic.h> #include <asm/io_apic.h> diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 5ed0ab549eb8..f9242800bc84 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c @@ -550,6 +550,7 @@ static void __exit microcode_exit(void) microcode_dev_exit(); unregister_hotcpu_notifier(&mc_cpu_notifier); + unregister_syscore_ops(&mc_syscore_ops); get_online_cpus(); mutex_lock(µcode_mutex); diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index d3ce37edb54d..08c44b08bf5b 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -6,6 +6,7 @@ #include <linux/dmi.h> #include <linux/sched.h> #include <linux/tboot.h> +#include <linux/delay.h> #include <acpi/reboot.h> #include <asm/io.h> #include <asm/apic.h> diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 8dace181c88e..cf9750004a08 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -49,6 +49,10 @@ u64 op_x86_get_ctrl(struct op_x86_model_spec const *model, val |= counter_config->user ? ARCH_PERFMON_EVENTSEL_USR : 0; val |= counter_config->kernel ? ARCH_PERFMON_EVENTSEL_OS : 0; val |= (counter_config->unit_mask & 0xFF) << 8; + counter_config->extra &= (ARCH_PERFMON_EVENTSEL_INV | + ARCH_PERFMON_EVENTSEL_EDGE | + ARCH_PERFMON_EVENTSEL_CMASK); + val |= counter_config->extra; event &= model->event_mask ? model->event_mask : 0xFF; val |= event & 0xFF; val |= (event & 0x0F00) << 24; @@ -440,6 +444,7 @@ static int nmi_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); + oprofilefs_create_ulong(sb, dir, "extra", &counter_config[i].extra); } return 0; diff --git a/arch/x86/oprofile/op_counter.h b/arch/x86/oprofile/op_counter.h index e28398df0df2..0b7b7b179cbe 100644 --- a/arch/x86/oprofile/op_counter.h +++ b/arch/x86/oprofile/op_counter.h @@ -22,6 +22,7 @@ struct op_counter_config { unsigned long kernel; unsigned long user; unsigned long unit_mask; + unsigned long extra; }; extern struct op_counter_config counter_config[]; diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c index a7b38d35c29a..7cb6424317f6 100644 --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c @@ -11,6 +11,7 @@ #include <linux/debugfs.h> #include <linux/kernel.h> #include <linux/slab.h> +#include <linux/delay.h> #include <asm/mmu_context.h> #include <asm/uv/uv.h> diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 1d730b5579a0..7c275f5d0df0 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -9,7 +9,6 @@ config XTENSA select HAVE_IDE select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW - select GENERIC_HARDIRQS_NO_DEPRECATED help Xtensa processors are 32-bit RISC machines designed by Tensilica primarily for embedded systems. These processors are both diff --git a/block/blk-core.c b/block/blk-core.c index e0a062363937..725091d5496d 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2163,7 +2163,7 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes) * size, something has gone terribly wrong. */ if (blk_rq_bytes(req) < blk_rq_cur_bytes(req)) { - printk(KERN_ERR "blk: request botched\n"); + blk_dump_rq_flags(req, "request botched"); req->__data_len = blk_rq_cur_bytes(req); } @@ -2665,7 +2665,7 @@ static int plug_rq_cmp(void *priv, struct list_head *a, struct list_head *b) struct request *rqa = container_of(a, struct request, queuelist); struct request *rqb = container_of(b, struct request, queuelist); - return !(rqa->q == rqb->q); + return !(rqa->q <= rqb->q); } static void flush_plug_list(struct blk_plug *plug) diff --git a/block/blk-flush.c b/block/blk-flush.c index 93d5fd8e51eb..eba4a2790c6c 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -261,7 +261,7 @@ static bool blk_kick_flush(struct request_queue *q) q->flush_rq.end_io = flush_end_io; q->flush_pending_idx ^= 1; - elv_insert(q, &q->flush_rq, ELEVATOR_INSERT_REQUEUE); + list_add_tail(&q->flush_rq.queuelist, &q->queue_head); return true; } @@ -281,7 +281,7 @@ static void flush_data_end_io(struct request *rq, int error) * blk_insert_flush - insert a new FLUSH/FUA request * @rq: request to insert * - * To be called from elv_insert() for %ELEVATOR_INSERT_FLUSH insertions. + * To be called from __elv_add_request() for %ELEVATOR_INSERT_FLUSH insertions. * @rq is being submitted. Analyze what needs to be done and put it on the * right queue. * @@ -312,7 +312,7 @@ void blk_insert_flush(struct request *rq) */ if ((policy & REQ_FSEQ_DATA) && !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) { - list_add(&rq->queuelist, &q->queue_head); + list_add_tail(&rq->queuelist, &q->queue_head); return; } diff --git a/block/blk-integrity.c b/block/blk-integrity.c index 54bcba6c02a7..129b9e209a3b 100644 --- a/block/blk-integrity.c +++ b/block/blk-integrity.c @@ -30,6 +30,8 @@ static struct kmem_cache *integrity_cachep; +static const char *bi_unsupported_name = "unsupported"; + /** * blk_rq_count_integrity_sg - Count number of integrity scatterlist elements * @q: request queue @@ -358,6 +360,14 @@ static struct kobj_type integrity_ktype = { .release = blk_integrity_release, }; +bool blk_integrity_is_initialized(struct gendisk *disk) +{ + struct blk_integrity *bi = blk_get_integrity(disk); + + return (bi && bi->name && strcmp(bi->name, bi_unsupported_name) != 0); +} +EXPORT_SYMBOL(blk_integrity_is_initialized); + /** * blk_integrity_register - Register a gendisk as being integrity-capable * @disk: struct gendisk pointer to make integrity-aware @@ -407,7 +417,7 @@ int blk_integrity_register(struct gendisk *disk, struct blk_integrity *template) bi->get_tag_fn = template->get_tag_fn; bi->tag_size = template->tag_size; } else - bi->name = "unsupported"; + bi->name = bi_unsupported_name; return 0; } diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 5352bdafbcf0..6c98cfeeedf0 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -77,7 +77,7 @@ struct throtl_grp { unsigned long slice_end[2]; /* Some throttle limits got updated for the group */ - bool limits_changed; + int limits_changed; }; struct throtl_data @@ -102,7 +102,7 @@ struct throtl_data /* Work for dispatching throttled bios */ struct delayed_work throtl_work; - bool limits_changed; + int limits_changed; }; enum tg_state_flags { diff --git a/block/elevator.c b/block/elevator.c index c387d3168734..0cdb4e7ebab4 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -610,7 +610,7 @@ void elv_requeue_request(struct request_queue *q, struct request *rq) rq->cmd_flags &= ~REQ_STARTED; - elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); + __elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE); } void elv_drain_elevator(struct request_queue *q) @@ -655,12 +655,25 @@ void elv_quiesce_end(struct request_queue *q) queue_flag_clear(QUEUE_FLAG_ELVSWITCH, q); } -void elv_insert(struct request_queue *q, struct request *rq, int where) +void __elv_add_request(struct request_queue *q, struct request *rq, int where) { trace_block_rq_insert(q, rq); rq->q = q; + BUG_ON(rq->cmd_flags & REQ_ON_PLUG); + + if (rq->cmd_flags & REQ_SOFTBARRIER) { + /* barriers are scheduling boundary, update end_sector */ + if (rq->cmd_type == REQ_TYPE_FS || + (rq->cmd_flags & REQ_DISCARD)) { + q->end_sector = rq_end_sector(rq); + q->boundary_rq = rq; + } + } else if (!(rq->cmd_flags & REQ_ELVPRIV) && + where == ELEVATOR_INSERT_SORT) + where = ELEVATOR_INSERT_BACK; + switch (where) { case ELEVATOR_INSERT_REQUEUE: case ELEVATOR_INSERT_FRONT: @@ -722,24 +735,6 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) BUG(); } } - -void __elv_add_request(struct request_queue *q, struct request *rq, int where) -{ - BUG_ON(rq->cmd_flags & REQ_ON_PLUG); - - if (rq->cmd_flags & REQ_SOFTBARRIER) { - /* barriers are scheduling boundary, update end_sector */ - if (rq->cmd_type == REQ_TYPE_FS || - (rq->cmd_flags & REQ_DISCARD)) { - q->end_sector = rq_end_sector(rq); - q->boundary_rq = rq; - } - } else if (!(rq->cmd_flags & REQ_ELVPRIV) && - where == ELEVATOR_INSERT_SORT) - where = ELEVATOR_INSERT_BACK; - - elv_insert(q, rq, where); -} EXPORT_SYMBOL(__elv_add_request); void elv_add_request(struct request_queue *q, struct request *rq, int where) diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c index a2a73d953840..b86d7e22595e 100644 --- a/drivers/ata/pata_palmld.c +++ b/drivers/ata/pata_palmld.c @@ -33,6 +33,11 @@ #define DRV_NAME "pata_palmld" +static struct gpio palmld_hdd_gpios[] = { + { GPIO_NR_PALMLD_IDE_PWEN, GPIOF_INIT_HIGH, "HDD Power" }, + { GPIO_NR_PALMLD_IDE_RESET, GPIOF_INIT_LOW, "HDD Reset" }, +}; + static struct scsi_host_template palmld_sht = { ATA_PIO_SHT(DRV_NAME), }; @@ -52,28 +57,23 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) /* allocate host */ host = ata_host_alloc(&pdev->dev, 1); - if (!host) - return -ENOMEM; + if (!host) { + ret = -ENOMEM; + goto err1; + } /* remap drive's physical memory address */ mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000); - if (!mem) - return -ENOMEM; + if (!mem) { + ret = -ENOMEM; + goto err1; + } /* request and activate power GPIO, IRQ GPIO */ - ret = gpio_request(GPIO_NR_PALMLD_IDE_PWEN, "HDD PWR"); + ret = gpio_request_array(palmld_hdd_gpios, + ARRAY_SIZE(palmld_hdd_gpios)); if (ret) goto err1; - ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_PWEN, 1); - if (ret) - goto err2; - - ret = gpio_request(GPIO_NR_PALMLD_IDE_RESET, "HDD RST"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_RESET, 0); - if (ret) - goto err3; /* reset the drive */ gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0); @@ -96,13 +96,15 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev) ata_sff_std_ports(&ap->ioaddr); /* activate host */ - return ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING, + ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING, &palmld_sht); + if (ret) + goto err2; + + return ret; -err3: - gpio_free(GPIO_NR_PALMLD_IDE_RESET); err2: - gpio_free(GPIO_NR_PALMLD_IDE_PWEN); + gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios)); err1: return ret; } @@ -116,8 +118,7 @@ static __devexit int palmld_pata_remove(struct platform_device *dev) /* power down the HDD */ gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0); - gpio_free(GPIO_NR_PALMLD_IDE_RESET); - gpio_free(GPIO_NR_PALMLD_IDE_PWEN); + gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios)); return 0; } diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 25ef1a4556e6..cd0ff66469b2 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -165,7 +165,6 @@ static uint32_t fpga_tx(struct solos_card *); static irqreturn_t solos_irq(int irq, void *dev_id); static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); static int list_vccs(int vci); -static void release_vccs(struct atm_dev *dev); static int atm_init(struct solos_card *, struct device *); static void atm_remove(struct solos_card *); static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); @@ -384,7 +383,6 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb /* Anything but 'Showtime' is down */ if (strcmp(state_str, "Showtime")) { atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST); - release_vccs(card->atmdev[port]); dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str); return 0; } @@ -697,7 +695,7 @@ void solos_bh(unsigned long card_arg) size); } if (atmdebug) { - dev_info(&card->dev->dev, "Received: device %d\n", port); + dev_info(&card->dev->dev, "Received: port %d\n", port); dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n", size, le16_to_cpu(header->vpi), le16_to_cpu(header->vci)); @@ -710,8 +708,8 @@ void solos_bh(unsigned long card_arg) le16_to_cpu(header->vci)); if (!vcc) { if (net_ratelimit()) - dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n", - le16_to_cpu(header->vci), le16_to_cpu(header->vpi), + dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n", + le16_to_cpu(header->vpi), le16_to_cpu(header->vci), port); continue; } @@ -830,28 +828,6 @@ static int list_vccs(int vci) return num_found; } -static void release_vccs(struct atm_dev *dev) -{ - int i; - - write_lock_irq(&vcc_sklist_lock); - for (i = 0; i < VCC_HTABLE_SIZE; i++) { - struct hlist_head *head = &vcc_hash[i]; - struct hlist_node *node, *tmp; - struct sock *s; - struct atm_vcc *vcc; - - sk_for_each_safe(s, node, tmp, head) { - vcc = atm_sk(s); - if (vcc->dev == dev) { - vcc_release_async(vcc, -EPIPE); - sk_del_node_init(s); - } - } - } - write_unlock_irq(&vcc_sklist_lock); -} - static int popen(struct atm_vcc *vcc) { @@ -1018,8 +994,15 @@ static uint32_t fpga_tx(struct solos_card *card) /* Clean up and free oldskb now it's gone */ if (atmdebug) { + struct pkt_hdr *header = (void *)oldskb->data; + int size = le16_to_cpu(header->size); + + skb_pull(oldskb, sizeof(*header)); dev_info(&card->dev->dev, "Transmitted: port %d\n", port); + dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n", + size, le16_to_cpu(header->vpi), + le16_to_cpu(header->vci)); print_buffer(oldskb); } @@ -1262,7 +1245,7 @@ static int atm_init(struct solos_card *card, struct device *parent) card->atmdev[i]->ci_range.vci_bits = 16; card->atmdev[i]->dev_data = card; card->atmdev[i]->phy_data = (void *)(unsigned long)i; - atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN); + atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND); skb = alloc_skb(sizeof(*header), GFP_ATOMIC); if (!skb) { diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 866811428e20..762a5109c68a 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -71,6 +71,9 @@ static struct usb_device_id btusb_table[] = { /* Apple MacBookAir3,1, MacBookAir3,2 */ { USB_DEVICE(0x05ac, 0x821b) }, + /* Apple MacBookPro8,2 */ + { USB_DEVICE(0x05ac, 0x821a) }, + /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, @@ -690,7 +693,8 @@ static int btusb_send_frame(struct sk_buff *skb) break; case HCI_ACLDATA_PKT: - if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1) + if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 && + hdev->conn_hash.le_num < 1)) return -ENODEV; urb = usb_alloc_urb(0, GFP_ATOMIC); diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 55653aba6735..c42c9d517790 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c @@ -31,24 +31,9 @@ #include <linux/connector.h> #include <linux/delay.h> -void cn_queue_wrapper(struct work_struct *work) -{ - struct cn_callback_entry *cbq = - container_of(work, struct cn_callback_entry, work); - struct cn_callback_data *d = &cbq->data; - struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb)); - struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb); - - d->callback(msg, nsp); - - kfree_skb(d->skb); - d->skb = NULL; - - kfree(d->free); -} - static struct cn_callback_entry * -cn_queue_alloc_callback_entry(const char *name, struct cb_id *id, +cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name, + struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)) { struct cn_callback_entry *cbq; @@ -59,17 +44,23 @@ cn_queue_alloc_callback_entry(const char *name, struct cb_id *id, return NULL; } + atomic_set(&cbq->refcnt, 1); + + atomic_inc(&dev->refcnt); + cbq->pdev = dev; + snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name); memcpy(&cbq->id.id, id, sizeof(struct cb_id)); - cbq->data.callback = callback; - - INIT_WORK(&cbq->work, &cn_queue_wrapper); + cbq->callback = callback; return cbq; } -static void cn_queue_free_callback(struct cn_callback_entry *cbq) +void cn_queue_release_callback(struct cn_callback_entry *cbq) { - flush_workqueue(cbq->pdev->cn_queue); + if (!atomic_dec_and_test(&cbq->refcnt)) + return; + + atomic_dec(&cbq->pdev->refcnt); kfree(cbq); } @@ -85,13 +76,10 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, struct cn_callback_entry *cbq, *__cbq; int found = 0; - cbq = cn_queue_alloc_callback_entry(name, id, callback); + cbq = cn_queue_alloc_callback_entry(dev, name, id, callback); if (!cbq) return -ENOMEM; - atomic_inc(&dev->refcnt); - cbq->pdev = dev; - spin_lock_bh(&dev->queue_lock); list_for_each_entry(__cbq, &dev->queue_list, callback_entry) { if (cn_cb_equal(&__cbq->id.id, id)) { @@ -104,8 +92,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, spin_unlock_bh(&dev->queue_lock); if (found) { - cn_queue_free_callback(cbq); - atomic_dec(&dev->refcnt); + cn_queue_release_callback(cbq); return -EINVAL; } @@ -130,10 +117,8 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id) } spin_unlock_bh(&dev->queue_lock); - if (found) { - cn_queue_free_callback(cbq); - atomic_dec(&dev->refcnt); - } + if (found) + cn_queue_release_callback(cbq); } struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls) @@ -151,12 +136,6 @@ struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls) dev->nls = nls; - dev->cn_queue = alloc_ordered_workqueue(dev->name, 0); - if (!dev->cn_queue) { - kfree(dev); - return NULL; - } - return dev; } @@ -164,9 +143,6 @@ void cn_queue_free_dev(struct cn_queue_dev *dev) { struct cn_callback_entry *cbq, *n; - flush_workqueue(dev->cn_queue); - destroy_workqueue(dev->cn_queue); - spin_lock_bh(&dev->queue_lock); list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry) list_del(&cbq->callback_entry); diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index f7554de3be5e..d77005849af8 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -122,51 +122,28 @@ EXPORT_SYMBOL_GPL(cn_netlink_send); */ static int cn_call_callback(struct sk_buff *skb) { - struct cn_callback_entry *__cbq, *__new_cbq; + struct cn_callback_entry *i, *cbq = NULL; struct cn_dev *dev = &cdev; struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb)); + struct netlink_skb_parms *nsp = &NETLINK_CB(skb); int err = -ENODEV; spin_lock_bh(&dev->cbdev->queue_lock); - list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { - if (cn_cb_equal(&__cbq->id.id, &msg->id)) { - if (likely(!work_pending(&__cbq->work) && - __cbq->data.skb == NULL)) { - __cbq->data.skb = skb; - - if (queue_work(dev->cbdev->cn_queue, - &__cbq->work)) - err = 0; - else - err = -EINVAL; - } else { - struct cn_callback_data *d; - - err = -ENOMEM; - __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC); - if (__new_cbq) { - d = &__new_cbq->data; - d->skb = skb; - d->callback = __cbq->data.callback; - d->free = __new_cbq; - - INIT_WORK(&__new_cbq->work, - &cn_queue_wrapper); - - if (queue_work(dev->cbdev->cn_queue, - &__new_cbq->work)) - err = 0; - else { - kfree(__new_cbq); - err = -EINVAL; - } - } - } + list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) { + if (cn_cb_equal(&i->id.id, &msg->id)) { + atomic_inc(&i->refcnt); + cbq = i; break; } } spin_unlock_bh(&dev->cbdev->queue_lock); + if (cbq != NULL) { + cbq->callback(msg, nsp); + kfree_skb(skb); + cn_queue_release_callback(cbq); + } + return err; } diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index ffb5ad080bee..38ab8e2cd7f4 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -1147,13 +1147,14 @@ static struct platform_driver mpc85xx_mc_err_driver = { static void __init mpc85xx_mc_clear_rfxe(void *data) { orig_hid1[smp_processor_id()] = mfspr(SPRN_HID1); - mtspr(SPRN_HID1, (orig_hid1[smp_processor_id()] & ~0x20000)); + mtspr(SPRN_HID1, (orig_hid1[smp_processor_id()] & ~HID1_RFXE)); } #endif static int __init mpc85xx_mc_init(void) { int res = 0; + u32 pvr = 0; printk(KERN_INFO "Freescale(R) MPC85xx EDAC driver, " "(C) 2006 Montavista Software\n"); @@ -1183,12 +1184,17 @@ static int __init mpc85xx_mc_init(void) #endif #ifdef CONFIG_FSL_SOC_BOOKE - /* - * need to clear HID1[RFXE] to disable machine check int - * so we can catch it - */ - if (edac_op_state == EDAC_OPSTATE_INT) - on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0); + pvr = mfspr(SPRN_PVR); + + if ((PVR_VER(pvr) == PVR_VER_E500V1) || + (PVR_VER(pvr) == PVR_VER_E500V2)) { + /* + * need to clear HID1[RFXE] to disable machine check int + * so we can catch it + */ + if (edac_op_state == EDAC_OPSTATE_INT) + on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0); + } #endif return 0; @@ -1206,7 +1212,12 @@ static void __exit mpc85xx_mc_restore_hid1(void *data) static void __exit mpc85xx_mc_exit(void) { #ifdef CONFIG_FSL_SOC_BOOKE - on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0); + u32 pvr = mfspr(SPRN_PVR); + + if ((PVR_VER(pvr) == PVR_VER_E500V1) || + (PVR_VER(pvr) == PVR_VER_E500V2)) { + on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0); + } #endif #ifdef CONFIG_PCI platform_driver_unregister(&mpc85xx_pci_err_driver); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 9c595e3b9c20..adc9358c9bec 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1297,7 +1297,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, /** * Search EDID for CEA extension block. */ -static u8 *drm_find_cea_extension(struct edid *edid) +u8 *drm_find_cea_extension(struct edid *edid) { u8 *edid_ext = NULL; int i; @@ -1318,6 +1318,7 @@ static u8 *drm_find_cea_extension(struct edid *edid) return edid_ext; } +EXPORT_SYMBOL(drm_find_cea_extension); /** * drm_detect_hdmi_monitor - detect whether monitor is hdmi. diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 8342259f3160..d03fc05b39c0 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -269,21 +269,6 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) return ret; } -static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus) -{ - u8 buf; - struct i2c_msg msgs[] = { - { - .addr = 0xA0, - .flags = 0, - .len = 1, - .buf = &buf, - }, - }; - /* DDC monitor detect: Does it ACK a write to 0xA0? */ - return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; -} - static bool intel_crt_detect_ddc(struct drm_connector *connector) { struct intel_crt *crt = intel_attached_crt(connector); @@ -293,11 +278,6 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector) if (crt->base.type != INTEL_OUTPUT_ANALOG) return false; - if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) { - DRM_DEBUG_KMS("CRT detected via DDC:0xa0\n"); - return true; - } - if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { struct edid *edid; bool is_digital = false; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5daa991cb287..f5b0d8306d83 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -39,7 +39,7 @@ ret__ = -ETIMEDOUT; \ break; \ } \ - if (W && !in_dbg_master()) msleep(W); \ + if (W && !(in_atomic() || in_dbg_master())) msleep(W); \ } \ ret__; \ }) diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 82d04c5899d2..d3b903bce7c5 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -259,7 +259,7 @@ gmbus_xfer(struct i2c_adapter *adapter, if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) goto timeout; if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - return 0; + goto clear_err; val = I915_READ(GMBUS3 + reg_offset); do { @@ -287,7 +287,7 @@ gmbus_xfer(struct i2c_adapter *adapter, if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) goto timeout; if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - return 0; + goto clear_err; val = loop = 0; do { @@ -302,14 +302,31 @@ gmbus_xfer(struct i2c_adapter *adapter, if (i + 1 < num && wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) goto timeout; if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) - return 0; + goto clear_err; } - return num; + goto done; + +clear_err: + /* Toggle the Software Clear Interrupt bit. This has the effect + * of resetting the GMBUS controller and so clearing the + * BUS_ERROR raised by the slave's NAK. + */ + I915_WRITE(GMBUS1 + reg_offset, GMBUS_SW_CLR_INT); + I915_WRITE(GMBUS1 + reg_offset, 0); + +done: + /* Mark the GMBUS interface as disabled. We will re-enable it at the + * start of the next xfer, till then let it sleep. + */ + I915_WRITE(GMBUS0 + reg_offset, 0); + return i; timeout: DRM_INFO("GMBUS timed out, falling back to bit banging on pin %d [%s]\n", bus->reg0 & 0xff, bus->adapter.name); + I915_WRITE(GMBUS0 + reg_offset, 0); + /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ bus->force_bit = intel_gpio_create(dev_priv, bus->reg0 & 0xff); if (!bus->force_bit) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 1a311ad01116..a562bd2648c7 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -473,19 +473,13 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; - enum drm_connector_status status = connector_status_connected; + enum drm_connector_status status; status = intel_panel_detect(dev); if (status != connector_status_unknown) return status; - /* ACPI lid methods were generally unreliable in this generation, so - * don't even bother. - */ - if (IS_GEN2(dev) || IS_GEN3(dev)) - return connector_status_connected; - - return status; + return connector_status_connected; } /** @@ -835,25 +829,6 @@ static bool lvds_is_present_in_vbt(struct drm_device *dev, return false; } -static bool intel_lvds_ddc_probe(struct drm_device *dev, u8 pin) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u8 buf = 0; - struct i2c_msg msgs[] = { - { - .addr = 0xA0, - .flags = 0, - .len = 1, - .buf = &buf, - }, - }; - struct i2c_adapter *i2c = &dev_priv->gmbus[pin].adapter; - /* XXX this only appears to work when using GMBUS */ - if (intel_gmbus_is_forced_bit(i2c)) - return true; - return i2c_transfer(i2c, msgs, 1) == 1; -} - /** * intel_lvds_init - setup LVDS connectors on this device * @dev: drm device @@ -894,11 +869,6 @@ bool intel_lvds_init(struct drm_device *dev) } } - if (!intel_lvds_ddc_probe(dev, pin)) { - DRM_DEBUG_KMS("LVDS did not respond to DDC probe\n"); - return false; - } - intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); if (!intel_lvds) { return false; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index e8b04f4aed7e..b52e46018245 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -97,7 +97,7 @@ nouveau_gem_new(struct drm_device *dev, struct nouveau_channel *chan, return -ENOMEM; } - nvbo->bo.persistant_swap_storage = nvbo->gem->filp; + nvbo->bo.persistent_swap_storage = nvbo->gem->filp; nvbo->gem->driver_private = nvbo; return 0; } diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 10e41af6b026..b41ec59c7100 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1009,6 +1009,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, uint64_t fb_location; uint32_t fb_format, fb_pitch_pixels, tiling_flags; u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); + u32 tmp; int r; /* no fb bound */ @@ -1137,6 +1138,15 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); + /* pageflip setup */ + /* make sure flip is at vb rather than hb */ + tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); + tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; + WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); + + /* set pageflip to happen anywhere in vblank interval */ + WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); + if (!atomic && fb && fb != crtc->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); @@ -1167,6 +1177,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, uint64_t fb_location; uint32_t fb_format, fb_pitch_pixels, tiling_flags; u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; + u32 tmp; int r; /* no fb bound */ @@ -1294,6 +1305,15 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); + /* pageflip setup */ + /* make sure flip is at vb rather than hb */ + tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); + tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); + + /* set pageflip to happen anywhere in vblank interval */ + WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); + if (!atomic && fb && fb != crtc->fb) { radeon_fb = to_radeon_framebuffer(fb); rbo = gem_to_radeon_bo(radeon_fb->obj); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 941080a77940..0b0cc74c08c0 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -43,17 +43,6 @@ static void evergreen_pcie_gen2_enable(struct radeon_device *rdev); void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) { - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; - u32 tmp; - - /* make sure flip is at vb rather than hb */ - tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; - WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); - - /* set pageflip to happen anywhere in vblank interval */ - WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - /* enable the pflip int */ radeon_irq_kms_pflip_irq_get(rdev, crtc); } diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 02d5c415f499..99768d9d91da 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -675,7 +675,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ATOM_ENCODER_CAP_RECORD *cap_record; u16 caps = 0; - while (record->ucRecordType > 0 && + while (record->ucRecordSize > 0 && + record->ucRecordType > 0 && record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { switch (record->ucRecordType) { case ATOM_ENCODER_CAP_RECORD_TYPE: @@ -720,7 +721,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) break; } - while (record->ucRecordType > 0 && + while (record->ucRecordSize > 0 && + record->ucRecordType > 0 && record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { switch (record->ucRecordType) { case ATOM_I2C_RECORD_TYPE: @@ -782,10 +784,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) ATOM_HPD_INT_RECORD *hpd_record; ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; - while (record->ucRecordType > 0 - && record-> - ucRecordType <= - ATOM_MAX_OBJECT_RECORD_NUMBER) { + while (record->ucRecordSize > 0 && + record->ucRecordType > 0 && + record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { switch (record->ucRecordType) { case ATOM_I2C_RECORD_TYPE: i2c_record = diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index cf602e2d0718..8caf546c8e92 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -2079,6 +2079,19 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) DRM_MODE_CONNECTOR_DVII, &ddc_i2c, CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, &hpd); + /* TV - TV DAC */ + ddc_i2c.valid = false; + hpd.hpd = RADEON_HPD_NONE; + radeon_add_legacy_encoder(dev, + radeon_get_encoder_enum(dev, + ATOM_DEVICE_TV1_SUPPORT, + 2), + ATOM_DEVICE_TV1_SUPPORT); + radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, + DRM_MODE_CONNECTOR_SVIDEO, + &ddc_i2c, + CONNECTOR_OBJECT_ID_SVIDEO, + &hpd); break; default: DRM_INFO("Connector table: %d (invalid)\n", diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 19763f5df5e1..876cebc4b8ba 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -48,17 +48,6 @@ int rs600_mc_wait_for_idle(struct radeon_device *rdev); void rs600_pre_page_flip(struct radeon_device *rdev, int crtc) { - struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; - u32 tmp; - - /* make sure flip is at vb rather than hb */ - tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); - tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; - WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); - - /* set pageflip to happen anywhere in vblank interval */ - WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); - /* enable the pflip int */ radeon_irq_kms_pflip_irq_get(rdev, crtc); } diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 0b6a55ac2f87..2e618b5ac465 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1168,7 +1168,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, uint32_t page_alignment, unsigned long buffer_start, bool interruptible, - struct file *persistant_swap_storage, + struct file *persistent_swap_storage, size_t acc_size, void (*destroy) (struct ttm_buffer_object *)) { @@ -1211,7 +1211,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, bo->priv_flags = 0; bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED); bo->seq_valid = false; - bo->persistant_swap_storage = persistant_swap_storage; + bo->persistent_swap_storage = persistent_swap_storage; bo->acc_size = acc_size; atomic_inc(&bo->glob->bo_count); @@ -1260,7 +1260,7 @@ int ttm_bo_create(struct ttm_bo_device *bdev, uint32_t page_alignment, unsigned long buffer_start, bool interruptible, - struct file *persistant_swap_storage, + struct file *persistent_swap_storage, struct ttm_buffer_object **p_bo) { struct ttm_buffer_object *bo; @@ -1282,7 +1282,7 @@ int ttm_bo_create(struct ttm_bo_device *bdev, ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment, buffer_start, interruptible, - persistant_swap_storage, acc_size, NULL); + persistent_swap_storage, acc_size, NULL); if (likely(ret == 0)) *p_bo = bo; @@ -1863,7 +1863,7 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) if (bo->bdev->driver->swap_notify) bo->bdev->driver->swap_notify(bo); - ret = ttm_tt_swapout(bo->ttm, bo->persistant_swap_storage); + ret = ttm_tt_swapout(bo->ttm, bo->persistent_swap_storage); out: /** diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 86d5b1745a45..90e23e0bfadb 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -332,7 +332,7 @@ void ttm_tt_destroy(struct ttm_tt *ttm) ttm_tt_free_page_directory(ttm); } - if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTANT_SWAP) && + if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP) && ttm->swap_storage) fput(ttm->swap_storage); @@ -503,7 +503,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) page_cache_release(from_page); } - if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTANT_SWAP)) + if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP)) fput(swap_storage); ttm->swap_storage = NULL; ttm->page_flags &= ~TTM_PAGE_FLAG_SWAPPED; @@ -514,7 +514,7 @@ out_err: return ret; } -int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) +int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) { struct address_space *swap_space; struct file *swap_storage; @@ -540,7 +540,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) return 0; } - if (!persistant_swap_storage) { + if (!persistent_swap_storage) { swap_storage = shmem_file_setup("ttm swap", ttm->num_pages << PAGE_SHIFT, 0); @@ -549,7 +549,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) return PTR_ERR(swap_storage); } } else - swap_storage = persistant_swap_storage; + swap_storage = persistent_swap_storage; swap_space = swap_storage->f_path.dentry->d_inode->i_mapping; @@ -577,12 +577,12 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistant_swap_storage) ttm_tt_free_alloced_pages(ttm); ttm->swap_storage = swap_storage; ttm->page_flags |= TTM_PAGE_FLAG_SWAPPED; - if (persistant_swap_storage) - ttm->page_flags |= TTM_PAGE_FLAG_PERSISTANT_SWAP; + if (persistent_swap_storage) + ttm->page_flags |= TTM_PAGE_FLAG_PERSISTENT_SWAP; return 0; out_err: - if (!persistant_swap_storage) + if (!persistent_swap_storage) fput(swap_storage); return ret; diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 97e22bef85ab..de5819199e2e 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c @@ -154,4 +154,4 @@ module_exit(twl4030_madc_hwmon_exit); MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("J Keerthy"); -MODULE_ALIAS("twl4030_madc_hwmon"); +MODULE_ALIAS("platform:twl4030_madc_hwmon"); diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 0e406d73b2c8..177db6d5b2f5 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -430,6 +430,26 @@ static inline void ide_unlock_host(struct ide_host *host) } } +static void __ide_requeue_and_plug(struct request_queue *q, struct request *rq) +{ + if (rq) + blk_requeue_request(q, rq); + if (rq || blk_peek_request(q)) { + /* Use 3ms as that was the old plug delay */ + blk_delay_queue(q, 3); + } +} + +void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) +{ + struct request_queue *q = drive->queue; + unsigned long flags; + + spin_lock_irqsave(q->queue_lock, flags); + __ide_requeue_and_plug(q, rq); + spin_unlock_irqrestore(q->queue_lock, flags); +} + /* * Issue a new request to a device. */ @@ -550,28 +570,7 @@ plug_device: ide_unlock_host(host); plug_device_2: spin_lock_irq(q->queue_lock); - - if (rq) { - blk_requeue_request(q, rq); - blk_delay_queue(q, queue_run_ms); - } -} - -void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) -{ - struct request_queue *q = drive->queue; - unsigned long flags; - - spin_lock_irqsave(q->queue_lock, flags); - - if (rq) - blk_requeue_request(q, rq); - - spin_unlock_irqrestore(q->queue_lock, flags); - - /* Use 3ms as that was the old plug delay */ - if (rq) - blk_delay_queue(q, 3); + __ide_requeue_and_plug(q, rq); } static int drive_is_ready(ide_drive_t *drive) diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index bee03d64c453..d712dffd2157 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -69,7 +69,7 @@ static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id) u8 sts, val; sts = readb(kbd->io_base + STATUS_REG); - if (sts & DATA_AVAIL) + if (!(sts & DATA_AVAIL)) return IRQ_NONE; if (kbd->last_key != KEY_RESERVED) { diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 364bdf43a381..736056897e50 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -302,10 +302,14 @@ static int uinput_validate_absbits(struct input_dev *dev) int retval = 0; for (cnt = 0; cnt < ABS_CNT; cnt++) { + int min, max; if (!test_bit(cnt, dev->absbit)) continue; - if (input_abs_get_max(dev, cnt) <= input_abs_get_min(dev, cnt)) { + min = input_abs_get_min(dev, cnt); + max = input_abs_get_max(dev, cnt); + + if ((min != 0 || max != 0) && max <= min) { printk(KERN_DEBUG "%s: invalid abs[%02x] min:%d max:%d\n", UINPUT_NAME, cnt, diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index aa186cf6c514..e06e045bf907 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -836,8 +836,8 @@ static const struct dmi_system_id __initconst toshiba_dmi_table[] = { }, }, - { } #endif + { } }; static bool broken_olpc_ec; @@ -851,8 +851,8 @@ static const struct dmi_system_id __initconst olpc_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "XO"), }, }, - { } #endif + { } }; void __init synaptics_module_init(void) diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index ac4c93689ab9..d37a48e099d0 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -869,15 +869,15 @@ static int i8042_controller_selftest(void) do { if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { - pr_err("i8042 controller self test timeout\n"); + pr_err("i8042 controller selftest timeout\n"); return -ENODEV; } if (param == I8042_RET_CTL_TEST) return 0; - pr_err("i8042 controller selftest failed. (%#x != %#x)\n", - param, I8042_RET_CTL_TEST); + dbg("i8042 controller selftest: %#x != %#x\n", + param, I8042_RET_CTL_TEST); msleep(50); } while (i++ < 5); @@ -891,6 +891,7 @@ static int i8042_controller_selftest(void) pr_info("giving up on controller selftest, continuing anyway...\n"); return 0; #else + pr_err("i8042 controller selftest failed\n"); return -EIO; #endif } diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 9da6fbcaaa7e..7ec3c97dc1b9 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -90,7 +90,7 @@ static int rpckbd_open(struct serio *port) if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) { printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n"); - free_irq(IRQ_KEYBOARDRX, NULL); + free_irq(IRQ_KEYBOARDRX, port); return -EBUSY; } diff --git a/drivers/input/sparse-keymap.c b/drivers/input/sparse-keymap.c index 337bf51bc984..fdb6a3976f94 100644 --- a/drivers/input/sparse-keymap.c +++ b/drivers/input/sparse-keymap.c @@ -208,6 +208,12 @@ int sparse_keymap_setup(struct input_dev *dev, } } + if (test_bit(EV_KEY, dev->evbit)) { + __set_bit(KEY_UNKNOWN, dev->keybit); + __set_bit(EV_MSC, dev->evbit); + __set_bit(MSC_SCAN, dev->mscbit); + } + dev->keycode = map; dev->keycodemax = map_size; dev->getkeycode = sparse_keymap_getkeycode; @@ -268,6 +274,7 @@ void sparse_keymap_report_entry(struct input_dev *dev, const struct key_entry *k { switch (ke->type) { case KE_KEY: + input_event(dev, EV_MSC, MSC_SCAN, ke->code); input_report_key(dev, ke->keycode, value); input_sync(dev); if (value && autorelease) { @@ -305,12 +312,19 @@ bool sparse_keymap_report_event(struct input_dev *dev, unsigned int code, { const struct key_entry *ke = sparse_keymap_entry_from_scancode(dev, code); + struct key_entry unknown_ke; if (ke) { sparse_keymap_report_entry(dev, ke, value, autorelease); return true; } + /* Report an unknown key event as a debugging aid */ + unknown_ke.type = KE_KEY; + unknown_ke.code = code; + unknown_ke.keycode = KEY_UNKNOWN; + sparse_keymap_report_entry(dev, &unknown_ke, value, true); + return false; } EXPORT_SYMBOL(sparse_keymap_report_event); diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 5597637cfd41..08ba5ad9c9be 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -16,6 +16,14 @@ #include "wacom.h" #include <linux/input/mt.h> +/* resolution for penabled devices */ +#define WACOM_PL_RES 20 +#define WACOM_PENPRTN_RES 40 +#define WACOM_VOLITO_RES 50 +#define WACOM_GRAPHIRE_RES 80 +#define WACOM_INTUOS_RES 100 +#define WACOM_INTUOS3_RES 200 + static int wacom_penpartner_irq(struct wacom_wac *wacom) { unsigned char *data = wacom->data; @@ -1055,6 +1063,19 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, features->pressure_fuzz, 0); + if (features->device_type == BTN_TOOL_PEN) { + /* penabled devices have fixed resolution for each model */ + input_abs_set_res(input_dev, ABS_X, features->x_resolution); + input_abs_set_res(input_dev, ABS_Y, features->y_resolution); + } else { + input_abs_set_res(input_dev, ABS_X, + wacom_calculate_touch_res(features->x_max, + features->x_phy)); + input_abs_set_res(input_dev, ABS_Y, + wacom_calculate_touch_res(features->y_max, + features->y_phy)); + } + __set_bit(ABS_MISC, input_dev->absbit); switch (wacom_wac->features.type) { @@ -1171,15 +1192,9 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, case TABLETPC: __clear_bit(ABS_MISC, input_dev->absbit); - if (features->device_type != BTN_TOOL_PEN) { - input_abs_set_res(input_dev, ABS_X, - wacom_calculate_touch_res(features->x_max, - features->x_phy)); - input_abs_set_res(input_dev, ABS_Y, - wacom_calculate_touch_res(features->y_max, - features->y_phy)); + if (features->device_type != BTN_TOOL_PEN) break; /* no need to process stylus stuff */ - } + /* fall through */ case PL: @@ -1216,12 +1231,6 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, features->pressure_max, features->pressure_fuzz, 0); - input_abs_set_res(input_dev, ABS_X, - wacom_calculate_touch_res(features->x_max, - features->x_phy)); - input_abs_set_res(input_dev, ABS_Y, - wacom_calculate_touch_res(features->y_max, - features->y_phy)); } else if (features->device_type == BTN_TOOL_PEN) { __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); __set_bit(BTN_TOOL_PEN, input_dev->keybit); @@ -1233,161 +1242,242 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, } static const struct wacom_features wacom_features_0x00 = - { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }; + { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, + 0, PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; static const struct wacom_features wacom_features_0x10 = - { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; + { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, + 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; static const struct wacom_features wacom_features_0x11 = - { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }; + { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, + 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; static const struct wacom_features wacom_features_0x12 = - { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }; + { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, + 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; static const struct wacom_features wacom_features_0x13 = - { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }; + { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, + 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; static const struct wacom_features wacom_features_0x14 = - { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; + { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, + 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; static const struct wacom_features wacom_features_0x15 = - { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }; + { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, + 63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; static const struct wacom_features wacom_features_0x16 = - { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }; + { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, + 63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; static const struct wacom_features wacom_features_0x17 = - { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; + { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, + 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x18 = - { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }; + { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, + 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x19 = - { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }; + { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, + 63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES }; static const struct wacom_features wacom_features_0x60 = - { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; + { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, + 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; static const struct wacom_features wacom_features_0x61 = - { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }; + { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, + 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; static const struct wacom_features wacom_features_0x62 = - { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; + { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, + 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; static const struct wacom_features wacom_features_0x63 = - { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }; + { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, + 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; static const struct wacom_features wacom_features_0x64 = - { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }; + { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, + 63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES }; static const struct wacom_features wacom_features_0x65 = - { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }; + { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, + 63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x69 = - { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }; + { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, + 63, GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES }; static const struct wacom_features wacom_features_0x20 = - { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; + { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x21 = - { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; + { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x22 = - { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; + { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x23 = - { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; + { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x24 = - { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; + { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x30 = - { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }; + { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x31 = - { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }; + { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x32 = - { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }; + { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x33 = - { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }; + { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x34 = - { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }; + { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x35 = - { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }; + { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x37 = - { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }; + { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x38 = - { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; + { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x39 = - { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }; + { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0xC4 = - { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }; + { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0xC0 = - { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; + { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0xC2 = - { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }; + { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, + 0, PL, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x03 = - { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }; + { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, + 0, PTU, WACOM_PL_RES, WACOM_PL_RES }; static const struct wacom_features wacom_features_0x41 = - { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }; + { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x42 = - { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; + { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x43 = - { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }; + { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x44 = - { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }; + { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x45 = - { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }; + { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0xB0 = - { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }; + { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, + 63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xB1 = - { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }; + { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, + 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xB2 = - { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }; + { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, + 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xB3 = - { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }; + { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, + 63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xB4 = - { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }; + { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, + 63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xB5 = - { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }; + { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, + 63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xB7 = - { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }; + { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, + 63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xB8 = - { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }; + { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, + 63, INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xB9 = - { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }; + { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, + 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xBA = - { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }; + { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, + 63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xBB = - { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }; + { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, + 63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xBC = - { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, 63, INTUOS4 }; + { "Wacom Intuos4 WL", WACOM_PKGLEN_INTUOS, 40840, 25400, 2047, + 63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0x3F = - { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }; + { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, + 63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xC5 = - { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }; + { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, + 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xC6 = - { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }; + { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, + 63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0xC7 = - { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }; + { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, + 0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0xCE = - { "Wacom DTU2231", WACOM_PKGLEN_GRAPHIRE, 47864, 27011, 511, 0, DTU }; + { "Wacom DTU2231", WACOM_PKGLEN_GRAPHIRE, 47864, 27011, 511, + 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0xF0 = - { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, 0, DTU }; + { "Wacom DTU1631", WACOM_PKGLEN_GRAPHIRE, 34623, 19553, 511, + 0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0xCC = - { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, 63, WACOM_21UX2 }; + { "Wacom Cintiq 21UX2", WACOM_PKGLEN_INTUOS, 87200, 65600, 2047, + 63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; static const struct wacom_features wacom_features_0x90 = - { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; + { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, + 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x93 = - { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; + { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, + 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x9A = - { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; + { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, + 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x9F = - { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }; + { "Wacom ISDv4 9F", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, + 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0xE2 = - { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; + { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, + 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0xE3 = - { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }; + { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, + 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xE6 = + { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, + 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x47 = - { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }; -static struct wacom_features wacom_features_0xD0 = - { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; -static struct wacom_features wacom_features_0xD1 = - { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; -static struct wacom_features wacom_features_0xD2 = - { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; -static struct wacom_features wacom_features_0xD3 = - { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; + { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, + 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xD0 = + { "Wacom Bamboo 2FG", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xD1 = + { "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xD2 = + { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xD3 = + { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0xD4 = - { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT }; -static struct wacom_features wacom_features_0xD6 = - { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; -static struct wacom_features wacom_features_0xD7 = - { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; -static struct wacom_features wacom_features_0xD8 = - { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; -static struct wacom_features wacom_features_0xDA = - { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; + { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xD6 = + { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xD7 = + { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xD8 = + { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0xDA = + { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static struct wacom_features wacom_features_0xDB = - { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; + { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, + 63, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x6004 = - { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, 0, TABLETPC }; + { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, + 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; #define USB_DEVICE_WACOM(prod) \ USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ @@ -1474,6 +1564,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0x9F) }, { USB_DEVICE_WACOM(0xE2) }, { USB_DEVICE_WACOM(0xE3) }, + { USB_DEVICE_WACOM(0xE6) }, { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_LENOVO(0x6004) }, { } diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 835f756b150c..53eb71b68330 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -74,6 +74,8 @@ struct wacom_features { int pressure_max; int distance_max; int type; + int x_resolution; + int y_resolution; int device_type; int x_phy; int y_phy; diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index b4d7f63deff1..efa06882de00 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c @@ -62,7 +62,7 @@ MODULE_LICENSE("GPL"); Programmer has no control over these numbers. TODO there are holes - specifically 1,7,0x0a */ -#define VERSION_ID 0 /* Get Version (request/respose) */ +#define VERSION_ID 0 /* Get Version (request/response) */ #define KEYBD_ID 2 /* Keyboard (event) */ #define TOUCHS_ID 3 /* Touch Screen (event)*/ #define EEPROM_READ_ID 4 /* (request/response) */ diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index bca2af2e3760..c987033714f6 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -153,7 +153,7 @@ static struct i2c_adapter * u3_0; static struct i2c_adapter * u3_1; static struct i2c_adapter * k2; static struct i2c_client * fcu; -static struct cpu_pid_state cpu_state[2]; +static struct cpu_pid_state processor_state[2]; static struct basckside_pid_params backside_params; static struct backside_pid_state backside_state; static struct drives_pid_state drives_state; @@ -664,8 +664,8 @@ static int read_eeprom(int cpu, struct mpu_data *out) static void fetch_cpu_pumps_minmax(void) { - struct cpu_pid_state *state0 = &cpu_state[0]; - struct cpu_pid_state *state1 = &cpu_state[1]; + struct cpu_pid_state *state0 = &processor_state[0]; + struct cpu_pid_state *state1 = &processor_state[1]; u16 pump_min = 0, pump_max = 0xffff; u16 tmp[4]; @@ -717,17 +717,17 @@ static ssize_t show_##name(struct device *dev, struct device_attribute *attr, ch return sprintf(buf, "%d", data); \ } -BUILD_SHOW_FUNC_FIX(cpu0_temperature, cpu_state[0].last_temp) -BUILD_SHOW_FUNC_FIX(cpu0_voltage, cpu_state[0].voltage) -BUILD_SHOW_FUNC_FIX(cpu0_current, cpu_state[0].current_a) -BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, cpu_state[0].rpm) -BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, cpu_state[0].intake_rpm) +BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp) +BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage) +BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a) +BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm) +BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm) -BUILD_SHOW_FUNC_FIX(cpu1_temperature, cpu_state[1].last_temp) -BUILD_SHOW_FUNC_FIX(cpu1_voltage, cpu_state[1].voltage) -BUILD_SHOW_FUNC_FIX(cpu1_current, cpu_state[1].current_a) -BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, cpu_state[1].rpm) -BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, cpu_state[1].intake_rpm) +BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp) +BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage) +BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a) +BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm) +BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm) BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp) BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm) @@ -919,8 +919,8 @@ static void do_cpu_pid(struct cpu_pid_state *state, s32 temp, s32 power) static void do_monitor_cpu_combined(void) { - struct cpu_pid_state *state0 = &cpu_state[0]; - struct cpu_pid_state *state1 = &cpu_state[1]; + struct cpu_pid_state *state0 = &processor_state[0]; + struct cpu_pid_state *state1 = &processor_state[1]; s32 temp0, power0, temp1, power1; s32 temp_combi, power_combi; int rc, intake, pump; @@ -1150,7 +1150,7 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state) /* * Initialize the state structure for one CPU control loop */ -static int init_cpu_state(struct cpu_pid_state *state, int index) +static int init_processor_state(struct cpu_pid_state *state, int index) { int err; @@ -1205,7 +1205,7 @@ static int init_cpu_state(struct cpu_pid_state *state, int index) /* * Dispose of the state data for one CPU control loop */ -static void dispose_cpu_state(struct cpu_pid_state *state) +static void dispose_processor_state(struct cpu_pid_state *state) { if (state->monitor == NULL) return; @@ -1804,9 +1804,9 @@ static int main_control_loop(void *x) set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM); /* Initialize ADCs */ - initialize_adc(&cpu_state[0]); - if (cpu_state[1].monitor != NULL) - initialize_adc(&cpu_state[1]); + initialize_adc(&processor_state[0]); + if (processor_state[1].monitor != NULL) + initialize_adc(&processor_state[1]); fcu_tickle_ticks = FCU_TICKLE_TICKS; @@ -1833,14 +1833,14 @@ static int main_control_loop(void *x) if (cpu_pid_type == CPU_PID_TYPE_COMBINED) do_monitor_cpu_combined(); else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) { - do_monitor_cpu_rack(&cpu_state[0]); - if (cpu_state[1].monitor != NULL) - do_monitor_cpu_rack(&cpu_state[1]); + do_monitor_cpu_rack(&processor_state[0]); + if (processor_state[1].monitor != NULL) + do_monitor_cpu_rack(&processor_state[1]); // better deal with UP } else { - do_monitor_cpu_split(&cpu_state[0]); - if (cpu_state[1].monitor != NULL) - do_monitor_cpu_split(&cpu_state[1]); + do_monitor_cpu_split(&processor_state[0]); + if (processor_state[1].monitor != NULL) + do_monitor_cpu_split(&processor_state[1]); // better deal with UP } /* Then, the rest */ @@ -1885,8 +1885,8 @@ static int main_control_loop(void *x) */ static void dispose_control_loops(void) { - dispose_cpu_state(&cpu_state[0]); - dispose_cpu_state(&cpu_state[1]); + dispose_processor_state(&processor_state[0]); + dispose_processor_state(&processor_state[1]); dispose_backside_state(&backside_state); dispose_drives_state(&drives_state); dispose_slots_state(&slots_state); @@ -1928,12 +1928,12 @@ static int create_control_loops(void) /* Create control loops for everything. If any fail, everything * fails */ - if (init_cpu_state(&cpu_state[0], 0)) + if (init_processor_state(&processor_state[0], 0)) goto fail; if (cpu_pid_type == CPU_PID_TYPE_COMBINED) fetch_cpu_pumps_minmax(); - if (cpu_count > 1 && init_cpu_state(&cpu_state[1], 1)) + if (cpu_count > 1 && init_processor_state(&processor_state[1], 1)) goto fail; if (init_backside_state(&backside_state)) goto fail; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 416d4e258df6..cb8380c9767f 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -927,20 +927,80 @@ static int dm_table_build_index(struct dm_table *t) } /* + * Get a disk whose integrity profile reflects the table's profile. + * If %match_all is true, all devices' profiles must match. + * If %match_all is false, all devices must at least have an + * allocated integrity profile; but uninitialized is ok. + * Returns NULL if integrity support was inconsistent or unavailable. + */ +static struct gendisk * dm_table_get_integrity_disk(struct dm_table *t, + bool match_all) +{ + struct list_head *devices = dm_table_get_devices(t); + struct dm_dev_internal *dd = NULL; + struct gendisk *prev_disk = NULL, *template_disk = NULL; + + list_for_each_entry(dd, devices, list) { + template_disk = dd->dm_dev.bdev->bd_disk; + if (!blk_get_integrity(template_disk)) + goto no_integrity; + if (!match_all && !blk_integrity_is_initialized(template_disk)) + continue; /* skip uninitialized profiles */ + else if (prev_disk && + blk_integrity_compare(prev_disk, template_disk) < 0) + goto no_integrity; + prev_disk = template_disk; + } + + return template_disk; + +no_integrity: + if (prev_disk) + DMWARN("%s: integrity not set: %s and %s profile mismatch", + dm_device_name(t->md), + prev_disk->disk_name, + template_disk->disk_name); + return NULL; +} + +/* * Register the mapped device for blk_integrity support if - * the underlying devices support it. + * the underlying devices have an integrity profile. But all devices + * may not have matching profiles (checking all devices isn't reliable + * during table load because this table may use other DM device(s) which + * must be resumed before they will have an initialized integity profile). + * Stacked DM devices force a 2 stage integrity profile validation: + * 1 - during load, validate all initialized integrity profiles match + * 2 - during resume, validate all integrity profiles match */ static int dm_table_prealloc_integrity(struct dm_table *t, struct mapped_device *md) { - struct list_head *devices = dm_table_get_devices(t); - struct dm_dev_internal *dd; + struct gendisk *template_disk = NULL; - list_for_each_entry(dd, devices, list) - if (bdev_get_integrity(dd->dm_dev.bdev)) { - t->integrity_supported = 1; - return blk_integrity_register(dm_disk(md), NULL); - } + template_disk = dm_table_get_integrity_disk(t, false); + if (!template_disk) + return 0; + if (!blk_integrity_is_initialized(dm_disk(md))) { + t->integrity_supported = 1; + return blk_integrity_register(dm_disk(md), NULL); + } + + /* + * If DM device already has an initalized integrity + * profile the new profile should not conflict. + */ + if (blk_integrity_is_initialized(template_disk) && + blk_integrity_compare(dm_disk(md), template_disk) < 0) { + DMWARN("%s: conflict with existing integrity profile: " + "%s profile mismatch", + dm_device_name(t->md), + template_disk->disk_name); + return 1; + } + + /* Preserve existing initialized integrity profile */ + t->integrity_supported = 1; return 0; } @@ -1094,41 +1154,27 @@ combine_limits: /* * Set the integrity profile for this device if all devices used have - * matching profiles. + * matching profiles. We're quite deep in the resume path but still + * don't know if all devices (particularly DM devices this device + * may be stacked on) have matching profiles. Even if the profiles + * don't match we have no way to fail (to resume) at this point. */ static void dm_table_set_integrity(struct dm_table *t) { - struct list_head *devices = dm_table_get_devices(t); - struct dm_dev_internal *prev = NULL, *dd = NULL; + struct gendisk *template_disk = NULL; if (!blk_get_integrity(dm_disk(t->md))) return; - list_for_each_entry(dd, devices, list) { - if (prev && - blk_integrity_compare(prev->dm_dev.bdev->bd_disk, - dd->dm_dev.bdev->bd_disk) < 0) { - DMWARN("%s: integrity not set: %s and %s mismatch", - dm_device_name(t->md), - prev->dm_dev.bdev->bd_disk->disk_name, - dd->dm_dev.bdev->bd_disk->disk_name); - goto no_integrity; - } - prev = dd; + template_disk = dm_table_get_integrity_disk(t, true); + if (!template_disk && + blk_integrity_is_initialized(dm_disk(t->md))) { + DMWARN("%s: device no longer has a valid integrity profile", + dm_device_name(t->md)); + return; } - - if (!prev || !bdev_get_integrity(prev->dm_dev.bdev)) - goto no_integrity; - blk_integrity_register(dm_disk(t->md), - bdev_get_integrity(prev->dm_dev.bdev)); - - return; - -no_integrity: - blk_integrity_register(dm_disk(t->md), NULL); - - return; + blk_get_integrity(template_disk)); } void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index 64454d39c0ca..ecfd9fb167d8 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -1494,12 +1494,17 @@ u32 fmc_prepare(struct fmdev *fmdev) } memset(&fm_st_proto, 0, sizeof(fm_st_proto)); - fm_st_proto.type = ST_FM; fm_st_proto.recv = fm_st_receive; fm_st_proto.match_packet = NULL; fm_st_proto.reg_complete_cb = fm_st_reg_comp_cb; fm_st_proto.write = NULL; /* TI ST driver will fill write pointer */ fm_st_proto.priv_data = fmdev; + fm_st_proto.chnl_id = 0x08; + fm_st_proto.max_frame_size = 0xff; + fm_st_proto.hdr_len = 1; + fm_st_proto.offset_len_in_hdr = 0; + fm_st_proto.len_size = 1; + fm_st_proto.reserve = 1; ret = st_register(&fm_st_proto); if (ret == -EINPROGRESS) { @@ -1532,7 +1537,7 @@ u32 fmc_prepare(struct fmdev *fmdev) g_st_write = fm_st_proto.write; } else { fmerr("Failed to get ST write func pointer\n"); - ret = st_unregister(ST_FM); + ret = st_unregister(&fm_st_proto); if (ret < 0) fmerr("st_unregister failed %d\n", ret); return -EAGAIN; @@ -1586,6 +1591,7 @@ u32 fmc_prepare(struct fmdev *fmdev) */ u32 fmc_release(struct fmdev *fmdev) { + static struct st_proto_s fm_st_proto; u32 ret; if (!test_bit(FM_CORE_READY, &fmdev->flag)) { @@ -1604,7 +1610,11 @@ u32 fmc_release(struct fmdev *fmdev) fmdev->resp_comp = NULL; fmdev->rx.freq = 0; - ret = st_unregister(ST_FM); + memset(&fm_st_proto, 0, sizeof(fm_st_proto)); + fm_st_proto.chnl_id = 0x08; + + ret = st_unregister(&fm_st_proto); + if (ret < 0) fmerr("Failed to de-register FM from ST %d\n", ret); else diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index ac0e42b47b2a..accaf6c9789a 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -41,6 +41,7 @@ #include <linux/bitops.h> #include <media/rc-core.h> #include <linux/pci_ids.h> +#include <linux/delay.h> #include "ite-cir.h" diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index e637e9f28fd4..937ef1afa5db 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -1996,13 +1996,15 @@ static int atl2_set_eeprom(struct net_device *netdev, if (!eeprom_buff) return -ENOMEM; - ptr = (u32 *)eeprom_buff; + ptr = eeprom_buff; if (eeprom->offset & 3) { /* need read/modify/write of first changed EEPROM word */ /* only the second byte of the word is being modified */ - if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) - return -EIO; + if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) { + ret_val = -EIO; + goto out; + } ptr++; } if (((eeprom->offset + eeprom->len) & 3)) { @@ -2011,18 +2013,22 @@ static int atl2_set_eeprom(struct net_device *netdev, * only the first byte of the word is being modified */ if (!atl2_read_eeprom(hw, last_dword * 4, - &(eeprom_buff[last_dword - first_dword]))) - return -EIO; + &(eeprom_buff[last_dword - first_dword]))) { + ret_val = -EIO; + goto out; + } } /* Device's eeprom is always little-endian, word addressable */ memcpy(ptr, bytes, eeprom->len); for (i = 0; i < last_dword - first_dword + 1; i++) { - if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) - return -EIO; + if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) { + ret_val = -EIO; + goto out; + } } - + out: kfree(eeprom_buff); return ret_val; } diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h index 118c28aa471e..4b3e35878406 100644 --- a/drivers/net/bonding/bond_alb.h +++ b/drivers/net/bonding/bond_alb.h @@ -74,7 +74,7 @@ struct tlb_client_info { * packets to a Client that the Hash function * gave this entry index. */ - u32 tx_bytes; /* Each Client acumulates the BytesTx that + u32 tx_bytes; /* Each Client accumulates the BytesTx that * were tranmitted to it, and after each * CallBack the LoadHistory is devided * by the balance interval diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 67c0ad42d818..186cd28a61cc 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -75,15 +75,9 @@ static int dongle_id = 0; /* default: probe */ /* We can't guess the type of connected dongle, user *must* supply it. */ module_param(dongle_id, int, 0); -/* FIXME : we should not need this, because instances should be automatically - * managed by the PCI layer. Especially that we seem to only be using the - * first entry. Jean II */ -/* Max 4 instances for now */ -static struct via_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL }; - /* Some prototypes */ -static int via_ircc_open(int i, chipio_t * info, unsigned int id); -static int via_ircc_close(struct via_ircc_cb *self); +static int via_ircc_open(struct pci_dev *pdev, chipio_t * info, + unsigned int id); static int via_ircc_dma_receive(struct via_ircc_cb *self); static int via_ircc_dma_receive_complete(struct via_ircc_cb *self, int iobase); @@ -215,7 +209,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0)); pci_write_config_byte(pcidev,0x5a,0xc0); WriteLPCReg(0x28, 0x70 ); - if (via_ircc_open(0, &info,0x3076) == 0) + if (via_ircc_open(pcidev, &info, 0x3076) == 0) rc=0; } else rc = -ENODEV; //IR not turn on @@ -254,7 +248,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi info.irq=FirIRQ; info.dma=FirDRQ1; info.dma2=FirDRQ0; - if (via_ircc_open(0, &info,0x3096) == 0) + if (via_ircc_open(pcidev, &info, 0x3096) == 0) rc=0; } else rc = -ENODEV; //IR not turn on !!!!! @@ -264,48 +258,10 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi return rc; } -/* - * Function via_ircc_clean () - * - * Close all configured chips - * - */ -static void via_ircc_clean(void) -{ - int i; - - IRDA_DEBUG(3, "%s()\n", __func__); - - for (i=0; i < ARRAY_SIZE(dev_self); i++) { - if (dev_self[i]) - via_ircc_close(dev_self[i]); - } -} - -static void __devexit via_remove_one (struct pci_dev *pdev) -{ - IRDA_DEBUG(3, "%s()\n", __func__); - - /* FIXME : This is ugly. We should use pci_get_drvdata(pdev); - * to get our driver instance and call directly via_ircc_close(). - * See vlsi_ir for details... - * Jean II */ - via_ircc_clean(); - - /* FIXME : This should be in via_ircc_close(), because here we may - * theoritically disable still configured devices :-( - Jean II */ - pci_disable_device(pdev); -} - static void __exit via_ircc_cleanup(void) { IRDA_DEBUG(3, "%s()\n", __func__); - /* FIXME : This should be redundant, as pci_unregister_driver() - * should call via_remove_one() on each device. - * Jean II */ - via_ircc_clean(); - /* Cleanup all instances of the driver */ pci_unregister_driver (&via_driver); } @@ -324,12 +280,13 @@ static const struct net_device_ops via_ircc_fir_ops = { }; /* - * Function via_ircc_open (iobase, irq) + * Function via_ircc_open(pdev, iobase, irq) * * Open driver instance * */ -static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) +static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info, + unsigned int id) { struct net_device *dev; struct via_ircc_cb *self; @@ -337,9 +294,6 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) IRDA_DEBUG(3, "%s()\n", __func__); - if (i >= ARRAY_SIZE(dev_self)) - return -ENOMEM; - /* Allocate new instance of the driver */ dev = alloc_irdadev(sizeof(struct via_ircc_cb)); if (dev == NULL) @@ -349,13 +303,8 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) self->netdev = dev; spin_lock_init(&self->lock); - /* FIXME : We should store our driver instance in the PCI layer, - * using pci_set_drvdata(), not in this array. - * See vlsi_ir for details... - Jean II */ - /* FIXME : 'i' is always 0 (see via_init_one()) :-( - Jean II */ - /* Need to store self somewhere */ - dev_self[i] = self; - self->index = i; + pci_set_drvdata(pdev, self); + /* Initialize Resource */ self->io.cfg_base = info->cfg_base; self->io.fir_base = info->fir_base; @@ -414,7 +363,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) /* Allocate memory if needed */ self->rx_buff.head = - dma_alloc_coherent(NULL, self->rx_buff.truesize, + dma_alloc_coherent(&pdev->dev, self->rx_buff.truesize, &self->rx_buff_dma, GFP_KERNEL); if (self->rx_buff.head == NULL) { err = -ENOMEM; @@ -423,7 +372,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) memset(self->rx_buff.head, 0, self->rx_buff.truesize); self->tx_buff.head = - dma_alloc_coherent(NULL, self->tx_buff.truesize, + dma_alloc_coherent(&pdev->dev, self->tx_buff.truesize, &self->tx_buff_dma, GFP_KERNEL); if (self->tx_buff.head == NULL) { err = -ENOMEM; @@ -455,33 +404,32 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id) via_hw_init(self); return 0; err_out4: - dma_free_coherent(NULL, self->tx_buff.truesize, + dma_free_coherent(&pdev->dev, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); err_out3: - dma_free_coherent(NULL, self->rx_buff.truesize, + dma_free_coherent(&pdev->dev, self->rx_buff.truesize, self->rx_buff.head, self->rx_buff_dma); err_out2: release_region(self->io.fir_base, self->io.fir_ext); err_out1: + pci_set_drvdata(pdev, NULL); free_netdev(dev); - dev_self[i] = NULL; return err; } /* - * Function via_ircc_close (self) + * Function via_remove_one(pdev) * * Close driver instance * */ -static int via_ircc_close(struct via_ircc_cb *self) +static void __devexit via_remove_one(struct pci_dev *pdev) { + struct via_ircc_cb *self = pci_get_drvdata(pdev); int iobase; IRDA_DEBUG(3, "%s()\n", __func__); - IRDA_ASSERT(self != NULL, return -1;); - iobase = self->io.fir_base; ResetChip(iobase, 5); //hardware reset. @@ -493,16 +441,16 @@ static int via_ircc_close(struct via_ircc_cb *self) __func__, self->io.fir_base); release_region(self->io.fir_base, self->io.fir_ext); if (self->tx_buff.head) - dma_free_coherent(NULL, self->tx_buff.truesize, + dma_free_coherent(&pdev->dev, self->tx_buff.truesize, self->tx_buff.head, self->tx_buff_dma); if (self->rx_buff.head) - dma_free_coherent(NULL, self->rx_buff.truesize, + dma_free_coherent(&pdev->dev, self->rx_buff.truesize, self->rx_buff.head, self->rx_buff_dma); - dev_self[self->index] = NULL; + pci_set_drvdata(pdev, NULL); free_netdev(self->netdev); - return 0; + pci_disable_device(pdev); } /* diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 506cfd0372ec..1ad1f6029af8 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -603,7 +603,9 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) } for (i = 0; i < dev->caps.num_comp_vectors; ++i) { - err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE, + err = mlx4_create_eq(dev, dev->caps.num_cqs - + dev->caps.reserved_cqs + + MLX4_NUM_SPARE_EQE, (dev->flags & MLX4_FLAG_MSI_X) ? i : 0, &priv->eq_table.eq[i]); if (err) { diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c index e71372aa9cc4..c6d336aed2d9 100644 --- a/drivers/net/mlx4/mcg.c +++ b/drivers/net/mlx4/mcg.c @@ -111,7 +111,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 vep_num, u8 port, u32 members_count; struct mlx4_steer_index *new_entry; struct mlx4_promisc_qp *pqp; - struct mlx4_promisc_qp *dqp; + struct mlx4_promisc_qp *dqp = NULL; u32 prot; int err; u8 pf_num; @@ -184,7 +184,7 @@ out_mailbox: out_alloc: if (dqp) { list_del(&dqp->list); - kfree(&dqp); + kfree(dqp); } list_del(&new_entry->list); kfree(new_entry); @@ -469,7 +469,6 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port, /*remove from list of promisc qps */ list_del(&pqp->list); - kfree(pqp); /* set the default entry not to include the removed one */ mailbox = mlx4_alloc_cmd_mailbox(dev); @@ -528,6 +527,8 @@ out_mailbox: out_list: if (back_to_list) list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]); + else + kfree(pqp); out_mutex: mutex_unlock(&priv->mcg_table.mutex); return err; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 993c52c82aeb..e870c0698bbe 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -442,11 +442,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, u32 flags, phy_interface_t interface) { struct device *d = &phydev->dev; + int err; /* Assume that if there is no driver, that it doesn't * exist, and we should use the genphy driver. */ if (NULL == d->driver) { - int err; d->driver = &genphy_driver.driver; err = d->driver->probe(d); @@ -474,7 +474,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, /* Do initial configuration here, now that * we have certain key parameters * (dev_flags and interface) */ - return phy_init_hw(phydev); + err = phy_init_hw(phydev); + if (err) + phy_detach(phydev); + + return err; } /** diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index a4f2bd52e546..36045f3b0327 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -144,11 +144,7 @@ static int full_duplex[MAX_UNITS] = {0, }; /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (2 * HZ) -/* - * This SUCKS. - * We need a much better method to determine if dma_addr_t is 64-bit. - */ -#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || (defined(CONFIG_MIPS) && ((defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || defined(CONFIG_64BIT))) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)) +#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT /* 64-bit dma_addr_t */ #define ADDR_64BITS /* This chip uses 64 bit addresses. */ #define netdrv_addr_t __le64 diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 6f600cced6e1..3ec22c307797 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -433,4 +433,19 @@ config USB_SIERRA_NET To compile this driver as a module, choose M here: the module will be called sierra_net. +config USB_VL600 + tristate "LG VL600 modem dongle" + depends on USB_NET_CDCETHER + select USB_ACM + help + Select this if you want to use an LG Electronics 4G/LTE usb modem + called VL600. This driver only handles the ethernet + interface exposed by the modem firmware. To establish a connection + you will first need a userspace program that sends the right + command to the modem through its CDC ACM port, and most + likely also a DHCP client. See this thread about using the + 4G modem from Verizon: + + http://ubuntuforums.org/showpost.php?p=10589647&postcount=17 + endmenu diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index cac170301187..c7ec8a5f0a90 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -27,4 +27,5 @@ obj-$(CONFIG_USB_IPHETH) += ipheth.o obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o +obj-$(CONFIG_USB_VL600) += lg-vl600.o diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index 5f3b97668e63..8f128541656d 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c @@ -340,7 +340,7 @@ next: static const struct driver_info eem_info = { .description = "CDC EEM Device", - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_POINTTOPOINT, .bind = eem_bind, .rx_fixup = eem_rx_fixup, .tx_fixup = eem_tx_fixup, diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 9a60e415d76b..341f7056a800 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds) __le32_to_cpu(speeds[1]) / 1000); } -static void cdc_status(struct usbnet *dev, struct urb *urb) +void usbnet_cdc_status(struct usbnet *dev, struct urb *urb) { struct usb_cdc_notification *event; @@ -418,8 +418,9 @@ static void cdc_status(struct usbnet *dev, struct urb *urb) break; } } +EXPORT_SYMBOL_GPL(usbnet_cdc_status); -static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) +int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf) { int status; struct cdc_state *info = (void *) &dev->data; @@ -441,6 +442,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf) */ return 0; } +EXPORT_SYMBOL_GPL(usbnet_cdc_bind); static int cdc_manage_power(struct usbnet *dev, int on) { @@ -450,20 +452,20 @@ static int cdc_manage_power(struct usbnet *dev, int on) static const struct driver_info cdc_info = { .description = "CDC Ethernet Device", - .flags = FLAG_ETHER, + .flags = FLAG_ETHER | FLAG_POINTTOPOINT, // .check_connect = cdc_check_connect, - .bind = cdc_bind, + .bind = usbnet_cdc_bind, .unbind = usbnet_cdc_unbind, - .status = cdc_status, + .status = usbnet_cdc_status, .manage_power = cdc_manage_power, }; static const struct driver_info mbm_info = { .description = "Mobile Broadband Network Device", .flags = FLAG_WWAN, - .bind = cdc_bind, + .bind = usbnet_cdc_bind, .unbind = usbnet_cdc_unbind, - .status = cdc_status, + .status = usbnet_cdc_status, .manage_power = cdc_manage_power, }; @@ -560,6 +562,13 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, +/* LG Electronics VL600 wants additional headers on every frame */ +{ + USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, + /* * WHITELIST!!! * diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 7113168473cf..967371f04454 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1237,7 +1237,7 @@ static int cdc_ncm_manage_power(struct usbnet *dev, int status) static const struct driver_info cdc_ncm_info = { .description = "CDC NCM", - .flags = FLAG_NO_SETINT | FLAG_MULTI_PACKET, + .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET, .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .check_connect = cdc_ncm_check_connect, diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c index ca39ace0b0eb..fc5f13d47ad9 100644 --- a/drivers/net/usb/cdc_subset.c +++ b/drivers/net/usb/cdc_subset.c @@ -89,6 +89,7 @@ static int always_connected (struct usbnet *dev) static const struct driver_info ali_m5632_info = { .description = "ALi M5632", + .flags = FLAG_POINTTOPOINT, }; #endif @@ -110,6 +111,7 @@ static const struct driver_info ali_m5632_info = { static const struct driver_info an2720_info = { .description = "AnchorChips/Cypress 2720", + .flags = FLAG_POINTTOPOINT, // no reset available! // no check_connect available! @@ -132,6 +134,7 @@ static const struct driver_info an2720_info = { static const struct driver_info belkin_info = { .description = "Belkin, eTEK, or compatible", + .flags = FLAG_POINTTOPOINT, }; #endif /* CONFIG_USB_BELKIN */ @@ -157,6 +160,7 @@ static const struct driver_info belkin_info = { static const struct driver_info epson2888_info = { .description = "Epson USB Device", .check_connect = always_connected, + .flags = FLAG_POINTTOPOINT, .in = 4, .out = 3, }; @@ -173,6 +177,7 @@ static const struct driver_info epson2888_info = { #define HAVE_HARDWARE static const struct driver_info kc2190_info = { .description = "KC Technology KC-190", + .flags = FLAG_POINTTOPOINT, }; #endif /* CONFIG_USB_KC2190 */ @@ -200,16 +205,19 @@ static const struct driver_info kc2190_info = { static const struct driver_info linuxdev_info = { .description = "Linux Device", .check_connect = always_connected, + .flags = FLAG_POINTTOPOINT, }; static const struct driver_info yopy_info = { .description = "Yopy", .check_connect = always_connected, + .flags = FLAG_POINTTOPOINT, }; static const struct driver_info blob_info = { .description = "Boot Loader OBject", .check_connect = always_connected, + .flags = FLAG_POINTTOPOINT, }; #endif /* CONFIG_USB_ARMLINUX */ diff --git a/drivers/net/usb/gl620a.c b/drivers/net/usb/gl620a.c index dcd57c37ef73..c4cfd1dea881 100644 --- a/drivers/net/usb/gl620a.c +++ b/drivers/net/usb/gl620a.c @@ -193,7 +193,7 @@ static int genelink_bind(struct usbnet *dev, struct usb_interface *intf) static const struct driver_info genelink_info = { .description = "Genesys GeneLink", - .flags = FLAG_FRAMING_GL | FLAG_NO_SETINT, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_GL | FLAG_NO_SETINT, .bind = genelink_bind, .rx_fixup = genelink_rx_fixup, .tx_fixup = genelink_tx_fixup, diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c new file mode 100644 index 000000000000..1d83ccfd7277 --- /dev/null +++ b/drivers/net/usb/lg-vl600.c @@ -0,0 +1,346 @@ +/* + * Ethernet interface part of the LG VL600 LTE modem (4G dongle) + * + * Copyright (C) 2011 Intel Corporation + * Author: Andrzej Zaborowski <balrogg@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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/etherdevice.h> +#include <linux/ethtool.h> +#include <linux/mii.h> +#include <linux/usb.h> +#include <linux/usb/cdc.h> +#include <linux/usb/usbnet.h> +#include <linux/if_ether.h> +#include <linux/if_arp.h> +#include <linux/inetdevice.h> + +/* + * The device has a CDC ACM port for modem control (it claims to be + * CDC ACM anyway) and a CDC Ethernet port for actual network data. + * It will however ignore data on both ports that is not encapsulated + * in a specific way, any data returned is also encapsulated the same + * way. The headers don't seem to follow any popular standard. + * + * This driver adds and strips these headers from the ethernet frames + * sent/received from the CDC Ethernet port. The proprietary header + * replaces the standard ethernet header in a packet so only actual + * ethernet frames are allowed. The headers allow some form of + * multiplexing by using non standard values of the .h_proto field. + * Windows/Mac drivers do send a couple of such frames to the device + * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what + * seems to be) a flag in the .dummy_flags. This doesn't seem necessary + * for modem operation but can possibly be used for GPS or other funcitons. + */ + +struct vl600_frame_hdr { + __le32 len; + __le32 serial; + __le32 pkt_cnt; + __le32 dummy_flags; + __le32 dummy; + __le32 magic; +} __attribute__((packed)); + +struct vl600_pkt_hdr { + __le32 dummy[2]; + __le32 len; + __be16 h_proto; +} __attribute__((packed)); + +struct vl600_state { + struct sk_buff *current_rx_buf; +}; + +static int vl600_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int ret; + struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL); + + if (!s) + return -ENOMEM; + + ret = usbnet_cdc_bind(dev, intf); + if (ret) { + kfree(s); + return ret; + } + + dev->driver_priv = s; + + /* ARP packets don't go through, but they're also of no use. The + * subnet has only two hosts anyway: us and the gateway / DHCP + * server (probably simulated by modem firmware or network operator) + * whose address changes everytime we connect to the intarwebz and + * who doesn't bother answering ARP requests either. So hardware + * addresses have no meaning, the destination and the source of every + * packet depend only on whether it is on the IN or OUT endpoint. */ + dev->net->flags |= IFF_NOARP; + + return ret; +} + +static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf) +{ + struct vl600_state *s = dev->driver_priv; + + if (s->current_rx_buf) + dev_kfree_skb(s->current_rx_buf); + + kfree(s); + + return usbnet_cdc_unbind(dev, intf); +} + +static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + struct vl600_frame_hdr *frame; + struct vl600_pkt_hdr *packet; + struct ethhdr *ethhdr; + int packet_len, count; + struct sk_buff *buf = skb; + struct sk_buff *clone; + struct vl600_state *s = dev->driver_priv; + + /* Frame lengths are generally 4B multiplies but every couple of + * hours there's an odd number of bytes sized yet correct frame, + * so don't require this. */ + + /* Allow a packet (or multiple packets batched together) to be + * split across many frames. We don't allow a new batch to + * begin in the same frame another one is ending however, and no + * leading or trailing pad bytes. */ + if (s->current_rx_buf) { + frame = (struct vl600_frame_hdr *) s->current_rx_buf->data; + if (skb->len + s->current_rx_buf->len > + le32_to_cpup(&frame->len)) { + netif_err(dev, ifup, dev->net, "Fragment too long\n"); + dev->net->stats.rx_length_errors++; + goto error; + } + + buf = s->current_rx_buf; + memcpy(skb_put(buf, skb->len), skb->data, skb->len); + } else if (skb->len < 4) { + netif_err(dev, ifup, dev->net, "Frame too short\n"); + dev->net->stats.rx_length_errors++; + goto error; + } + + frame = (struct vl600_frame_hdr *) buf->data; + /* NOTE: Should check that frame->magic == 0x53544448? + * Otherwise if we receive garbage at the beginning of the frame + * we may end up allocating a huge buffer and saving all the + * future incoming data into it. */ + + if (buf->len < sizeof(*frame) || + buf->len != le32_to_cpup(&frame->len)) { + /* Save this fragment for later assembly */ + if (s->current_rx_buf) + return 0; + + s->current_rx_buf = skb_copy_expand(skb, 0, + le32_to_cpup(&frame->len), GFP_ATOMIC); + if (!s->current_rx_buf) { + netif_err(dev, ifup, dev->net, "Reserving %i bytes " + "for packet assembly failed.\n", + le32_to_cpup(&frame->len)); + dev->net->stats.rx_errors++; + } + + return 0; + } + + count = le32_to_cpup(&frame->pkt_cnt); + + skb_pull(buf, sizeof(*frame)); + + while (count--) { + if (buf->len < sizeof(*packet)) { + netif_err(dev, ifup, dev->net, "Packet too short\n"); + goto error; + } + + packet = (struct vl600_pkt_hdr *) buf->data; + packet_len = sizeof(*packet) + le32_to_cpup(&packet->len); + if (packet_len > buf->len) { + netif_err(dev, ifup, dev->net, + "Bad packet length stored in header\n"); + goto error; + } + + /* Packet header is same size as the ethernet header + * (sizeof(*packet) == sizeof(*ethhdr)), additionally + * the h_proto field is in the same place so we just leave it + * alone and fill in the remaining fields. + */ + ethhdr = (struct ethhdr *) skb->data; + if (be16_to_cpup(ðhdr->h_proto) == ETH_P_ARP && + buf->len > 0x26) { + /* Copy the addresses from packet contents */ + memcpy(ethhdr->h_source, + &buf->data[sizeof(*ethhdr) + 0x8], + ETH_ALEN); + memcpy(ethhdr->h_dest, + &buf->data[sizeof(*ethhdr) + 0x12], + ETH_ALEN); + } else { + memset(ethhdr->h_source, 0, ETH_ALEN); + memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN); + } + + if (count) { + /* Not the last packet in this batch */ + clone = skb_clone(buf, GFP_ATOMIC); + if (!clone) + goto error; + + skb_trim(clone, packet_len); + usbnet_skb_return(dev, clone); + + skb_pull(buf, (packet_len + 3) & ~3); + } else { + skb_trim(buf, packet_len); + + if (s->current_rx_buf) { + usbnet_skb_return(dev, buf); + s->current_rx_buf = NULL; + return 0; + } + + return 1; + } + } + +error: + if (s->current_rx_buf) { + dev_kfree_skb_any(s->current_rx_buf); + s->current_rx_buf = NULL; + } + dev->net->stats.rx_errors++; + return 0; +} + +static struct sk_buff *vl600_tx_fixup(struct usbnet *dev, + struct sk_buff *skb, gfp_t flags) +{ + struct sk_buff *ret; + struct vl600_frame_hdr *frame; + struct vl600_pkt_hdr *packet; + static uint32_t serial = 1; + int orig_len = skb->len - sizeof(struct ethhdr); + int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3; + + frame = (struct vl600_frame_hdr *) skb->data; + if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len)) + return skb; /* Already encapsulated? */ + + if (skb->len < sizeof(struct ethhdr)) + /* Drop, device can only deal with ethernet packets */ + return NULL; + + if (!skb_cloned(skb)) { + int headroom = skb_headroom(skb); + int tailroom = skb_tailroom(skb); + + if (tailroom >= full_len - skb->len - sizeof(*frame) && + headroom >= sizeof(*frame)) + /* There's enough head and tail room */ + goto encapsulate; + + if (headroom + tailroom + skb->len >= full_len) { + /* There's enough total room, just readjust */ + skb->data = memmove(skb->head + sizeof(*frame), + skb->data, skb->len); + skb_set_tail_pointer(skb, skb->len); + goto encapsulate; + } + } + + /* Alloc a new skb with the required size */ + ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len - + skb->len - sizeof(struct vl600_frame_hdr), flags); + dev_kfree_skb_any(skb); + if (!ret) + return ret; + skb = ret; + +encapsulate: + /* Packet header is same size as ethernet packet header + * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the + * h_proto field is in the same place so we just leave it alone and + * overwrite the remaining fields. + */ + packet = (struct vl600_pkt_hdr *) skb->data; + memset(&packet->dummy, 0, sizeof(packet->dummy)); + packet->len = cpu_to_le32(orig_len); + + frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame)); + memset(frame, 0, sizeof(*frame)); + frame->len = cpu_to_le32(full_len); + frame->serial = cpu_to_le32(serial++); + frame->pkt_cnt = cpu_to_le32(1); + + if (skb->len < full_len) /* Pad */ + skb_put(skb, full_len - skb->len); + + return skb; +} + +static const struct driver_info vl600_info = { + .description = "LG VL600 modem", + .flags = FLAG_ETHER | FLAG_RX_ASSEMBLE, + .bind = vl600_bind, + .unbind = vl600_unbind, + .status = usbnet_cdc_status, + .rx_fixup = vl600_rx_fixup, + .tx_fixup = vl600_tx_fixup, +}; + +static const struct usb_device_id products[] = { + { + USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &vl600_info, + }, + {}, /* End */ +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver lg_vl600_driver = { + .name = "lg-vl600", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, +}; + +static int __init vl600_init(void) +{ + return usb_register(&lg_vl600_driver); +} +module_init(vl600_init); + +static void __exit vl600_exit(void) +{ + usb_deregister(&lg_vl600_driver); +} +module_exit(vl600_exit); + +MODULE_AUTHOR("Anrzej Zaborowski"); +MODULE_DESCRIPTION("LG-VL600 modem's ethernet link"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index ba72a7281cb0..01db4602a39e 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c @@ -560,7 +560,7 @@ static int net1080_bind(struct usbnet *dev, struct usb_interface *intf) static const struct driver_info net1080_info = { .description = "NetChip TurboCONNECT", - .flags = FLAG_FRAMING_NC, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_NC, .bind = net1080_bind, .reset = net1080_reset, .check_connect = net1080_check_connect, diff --git a/drivers/net/usb/plusb.c b/drivers/net/usb/plusb.c index 08ad269f6b4e..823c53751307 100644 --- a/drivers/net/usb/plusb.c +++ b/drivers/net/usb/plusb.c @@ -96,7 +96,7 @@ static int pl_reset(struct usbnet *dev) static const struct driver_info prolific_info = { .description = "Prolific PL-2301/PL-2302", - .flags = FLAG_NO_SETINT, + .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT, /* some PL-2302 versions seem to fail usb_set_interface() */ .reset = pl_reset, }; diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index dd8a4adf48ca..5994a25c56ac 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(rndis_tx_fixup); static const struct driver_info rndis_info = { .description = "RNDIS device", - .flags = FLAG_ETHER | FLAG_FRAMING_RN | FLAG_NO_SETINT, + .flags = FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT, .bind = rndis_bind, .unbind = rndis_unbind, .status = rndis_status, diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 95c41d56631c..069c1cf0fdf7 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -387,8 +387,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) { if (dev->driver_info->rx_fixup && - !dev->driver_info->rx_fixup (dev, skb)) - goto error; + !dev->driver_info->rx_fixup (dev, skb)) { + /* With RX_ASSEMBLE, rx_fixup() must update counters */ + if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE)) + dev->net->stats.rx_errors++; + goto done; + } // else network stack removes extra byte if we forced a short packet if (skb->len) { @@ -401,8 +405,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb) } netif_dbg(dev, rx_err, dev->net, "drop\n"); -error: dev->net->stats.rx_errors++; +done: skb_queue_tail(&dev->done, skb); } @@ -1376,7 +1380,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) // else "eth%d" when there's reasonable doubt. userspace // can rename the link if it knows better. if ((dev->driver_info->flags & FLAG_ETHER) != 0 && - (net->dev_addr [0] & 0x02) == 0) + ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || + (net->dev_addr [0] & 0x02) == 0)) strcpy (net->name, "eth%d"); /* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags & FLAG_WLAN) != 0) diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c index 3eb0b167b5b4..241756e0e86f 100644 --- a/drivers/net/usb/zaurus.c +++ b/drivers/net/usb/zaurus.c @@ -102,7 +102,7 @@ static int always_connected (struct usbnet *dev) static const struct driver_info zaurus_sl5x00_info = { .description = "Sharp Zaurus SL-5x00", - .flags = FLAG_FRAMING_Z, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, @@ -112,7 +112,7 @@ static const struct driver_info zaurus_sl5x00_info = { static const struct driver_info zaurus_pxa_info = { .description = "Sharp Zaurus, PXA-2xx based", - .flags = FLAG_FRAMING_Z, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, @@ -122,7 +122,7 @@ static const struct driver_info zaurus_pxa_info = { static const struct driver_info olympus_mxl_info = { .description = "Olympus R1000", - .flags = FLAG_FRAMING_Z, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, .check_connect = always_connected, .bind = zaurus_bind, .unbind = usbnet_cdc_unbind, @@ -258,7 +258,7 @@ bad_desc: static const struct driver_info bogus_mdlm_info = { .description = "pseudo-MDLM (BLAN) device", - .flags = FLAG_FRAMING_Z, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_Z, .check_connect = always_connected, .tx_fixup = zaurus_tx_fixup, .bind = blan_mdlm_bind, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 524825720a09..dddb85de622d 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1048,6 +1048,8 @@ static int ath9k_start(struct ieee80211_hw *hw) "Starting driver with initial channel: %d MHz\n", curchan->center_freq); + ath9k_ps_wakeup(sc); + mutex_lock(&sc->mutex); /* setup initial channel */ @@ -1143,6 +1145,8 @@ static int ath9k_start(struct ieee80211_hw *hw) mutex_unlock: mutex_unlock(&sc->mutex); + ath9k_ps_restore(sc); + return r; } diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index c6a5fae634a0..9cad061cc1d2 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -443,6 +443,7 @@ struct carl9170_ba_stats { u8 ampdu_len; u8 ampdu_ack_len; bool clear; + bool req; }; struct carl9170_sta_info { diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index ede3d7e5a048..89fe60accf85 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1355,6 +1355,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, tid_info = rcu_dereference(sta_info->agg[tid]); sta_info->stats[tid].clear = true; + sta_info->stats[tid].req = false; if (tid_info) { bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE); diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index 0ef70b6fc512..cb70ed7ec5cc 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -383,6 +383,7 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, if (sta_info->stats[tid].clear) { sta_info->stats[tid].clear = false; + sta_info->stats[tid].req = false; sta_info->stats[tid].ampdu_len = 0; sta_info->stats[tid].ampdu_ack_len = 0; } @@ -391,10 +392,16 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, if (txinfo->status.rates[0].count == 1) sta_info->stats[tid].ampdu_ack_len++; + if (!(txinfo->flags & IEEE80211_TX_STAT_ACK)) + sta_info->stats[tid].req = true; + if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { super->s.rix = sta_info->stats[tid].ampdu_len; super->s.cnt = sta_info->stats[tid].ampdu_ack_len; txinfo->flags |= IEEE80211_TX_STAT_AMPDU; + if (sta_info->stats[tid].req) + txinfo->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; + sta_info->stats[tid].clear = true; } spin_unlock_bh(&tid_info->lock); diff --git a/drivers/net/wireless/iwlegacy/iwl-core.c b/drivers/net/wireless/iwlegacy/iwl-core.c index d418b647be80..a209a0e76bf0 100644 --- a/drivers/net/wireless/iwlegacy/iwl-core.c +++ b/drivers/net/wireless/iwlegacy/iwl-core.c @@ -1805,6 +1805,15 @@ iwl_legacy_mac_change_interface(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + if (!ctx->vif || !iwl_legacy_is_ready_rf(priv)) { + /* + * Huh? But wait ... this can maybe happen when + * we're in the middle of a firmware restart! + */ + err = -EBUSY; + goto out; + } + interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes; if (!(interface_modes & BIT(newtype))) { @@ -1832,6 +1841,7 @@ iwl_legacy_mac_change_interface(struct ieee80211_hw *hw, /* success */ iwl_legacy_teardown_interface(priv, vif, true); vif->type = newtype; + vif->p2p = newp2p; err = iwl_legacy_setup_interface(priv, ctx); WARN_ON(err); /* diff --git a/drivers/net/wireless/iwlegacy/iwl3945-base.c b/drivers/net/wireless/iwlegacy/iwl3945-base.c index ab87e1b73529..28eb3d885ba1 100644 --- a/drivers/net/wireless/iwlegacy/iwl3945-base.c +++ b/drivers/net/wireless/iwlegacy/iwl3945-base.c @@ -93,6 +93,7 @@ MODULE_LICENSE("GPL"); struct iwl_mod_params iwl3945_mod_params = { .sw_crypto = 1, .restart_fw = 1, + .disable_hw_scan = 1, /* the rest are 0 by default */ }; @@ -3960,8 +3961,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e * "the hard way", rather than using device's scan. */ if (iwl3945_mod_params.disable_hw_scan) { - dev_printk(KERN_DEBUG, &(pdev->dev), - "sw scan support is deprecated\n"); + IWL_DEBUG_INFO(priv, "Disabling hw_scan\n"); iwl3945_hw_ops.hw_scan = NULL; } @@ -4280,8 +4280,7 @@ MODULE_PARM_DESC(swcrypto, "using software crypto (default 1 [software])"); module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, - "disable hardware scanning (default 0) (deprecated)"); +MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 1)"); #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG module_param_named(debug, iwlegacy_debug_level, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(debug, "debug output mask"); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 4e368657a83c..37509d019910 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -730,8 +730,12 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x050d, 0x825b), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x050d, 0x935a), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x050d, 0x935b), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Buffalo */ { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x0411, 0x016f), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Conceptronic */ { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -818,6 +822,7 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Pegatron */ { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) }, + { USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Philips */ { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Planex */ @@ -899,6 +904,8 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Sitecom */ { USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) }, + /* Toshiba */ + { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Zinwell */ { USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) }, #endif @@ -961,7 +968,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) }, - { USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Planex */ { USB_DEVICE(0x2019, 0x5201), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) }, @@ -975,8 +981,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Sweex */ { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) }, { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) }, - /* Toshiba */ - { USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) }, /* Zyxel */ { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) }, #endif diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c index a52039564e74..443cb7fc872d 100644 --- a/drivers/pcmcia/pxa2xx_colibri.c +++ b/drivers/pcmcia/pxa2xx_colibri.c @@ -34,14 +34,24 @@ #define COLIBRI320_DETECT_GPIO 81 #define COLIBRI320_READY_GPIO 29 -static struct { - int reset_gpio; - int ppen_gpio; - int bvd1_gpio; - int bvd2_gpio; - int detect_gpio; - int ready_gpio; -} colibri_pcmcia_gpio; +enum { + DETECT = 0, + READY = 1, + BVD1 = 2, + BVD2 = 3, + PPEN = 4, + RESET = 5, +}; + +/* Contents of this array are configured on-the-fly in init function */ +static struct gpio colibri_pcmcia_gpios[] = { + { 0, GPIOF_IN, "PCMCIA Detect" }, + { 0, GPIOF_IN, "PCMCIA Ready" }, + { 0, GPIOF_IN, "PCMCIA BVD1" }, + { 0, GPIOF_IN, "PCMCIA BVD2" }, + { 0, GPIOF_INIT_LOW, "PCMCIA PPEN" }, + { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" }, +}; static struct pcmcia_irqs colibri_irqs[] = { { @@ -54,88 +64,42 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT"); + ret = gpio_request_array(colibri_pcmcia_gpios, + ARRAY_SIZE(colibri_pcmcia_gpios)); if (ret) goto err1; - ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio); - if (ret) - goto err2; - - ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY"); - if (ret) - goto err2; - ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio); - if (ret) - goto err3; - ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1"); - if (ret) - goto err3; - ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio); - if (ret) - goto err4; + colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio); + skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio); - ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2"); - if (ret) - goto err4; - ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio); - if (ret) - goto err5; - - ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN"); - if (ret) - goto err5; - ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0); - if (ret) - goto err6; - - ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET"); - if (ret) - goto err6; - ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1); + ret = soc_pcmcia_request_irqs(skt, colibri_irqs, + ARRAY_SIZE(colibri_irqs)); if (ret) - goto err7; - - colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio); - skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio); + goto err2; - return soc_pcmcia_request_irqs(skt, colibri_irqs, - ARRAY_SIZE(colibri_irqs)); + return ret; -err7: - gpio_free(colibri_pcmcia_gpio.detect_gpio); -err6: - gpio_free(colibri_pcmcia_gpio.ready_gpio); -err5: - gpio_free(colibri_pcmcia_gpio.bvd1_gpio); -err4: - gpio_free(colibri_pcmcia_gpio.bvd2_gpio); -err3: - gpio_free(colibri_pcmcia_gpio.reset_gpio); err2: - gpio_free(colibri_pcmcia_gpio.ppen_gpio); + gpio_free_array(colibri_pcmcia_gpios, + ARRAY_SIZE(colibri_pcmcia_gpios)); err1: return ret; } static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(colibri_pcmcia_gpio.detect_gpio); - gpio_free(colibri_pcmcia_gpio.ready_gpio); - gpio_free(colibri_pcmcia_gpio.bvd1_gpio); - gpio_free(colibri_pcmcia_gpio.bvd2_gpio); - gpio_free(colibri_pcmcia_gpio.reset_gpio); - gpio_free(colibri_pcmcia_gpio.ppen_gpio); + gpio_free_array(colibri_pcmcia_gpios, + ARRAY_SIZE(colibri_pcmcia_gpios)); } static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio); - state->ready = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio); - state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio); - state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio); + state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio); + state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio); + state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio); + state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio); state->wrprot = 0; state->vs_3v = 1; state->vs_Xv = 0; @@ -145,9 +109,10 @@ static int colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { - gpio_set_value(colibri_pcmcia_gpio.ppen_gpio, + gpio_set_value(colibri_pcmcia_gpios[PPEN].gpio, !(state->Vcc == 33 && state->Vpp < 50)); - gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET); + gpio_set_value(colibri_pcmcia_gpios[RESET].gpio, + state->flags & SS_RESET); return 0; } @@ -190,20 +155,20 @@ static int __init colibri_pcmcia_init(void) /* Colibri PXA270 */ if (machine_is_colibri()) { - colibri_pcmcia_gpio.reset_gpio = COLIBRI270_RESET_GPIO; - colibri_pcmcia_gpio.ppen_gpio = COLIBRI270_PPEN_GPIO; - colibri_pcmcia_gpio.bvd1_gpio = COLIBRI270_BVD1_GPIO; - colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO; - colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO; - colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO; + colibri_pcmcia_gpios[RESET].gpio = COLIBRI270_RESET_GPIO; + colibri_pcmcia_gpios[PPEN].gpio = COLIBRI270_PPEN_GPIO; + colibri_pcmcia_gpios[BVD1].gpio = COLIBRI270_BVD1_GPIO; + colibri_pcmcia_gpios[BVD2].gpio = COLIBRI270_BVD2_GPIO; + colibri_pcmcia_gpios[DETECT].gpio = COLIBRI270_DETECT_GPIO; + colibri_pcmcia_gpios[READY].gpio = COLIBRI270_READY_GPIO; /* Colibri PXA320 */ } else if (machine_is_colibri320()) { - colibri_pcmcia_gpio.reset_gpio = COLIBRI320_RESET_GPIO; - colibri_pcmcia_gpio.ppen_gpio = COLIBRI320_PPEN_GPIO; - colibri_pcmcia_gpio.bvd1_gpio = COLIBRI320_BVD1_GPIO; - colibri_pcmcia_gpio.bvd2_gpio = COLIBRI320_BVD2_GPIO; - colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO; - colibri_pcmcia_gpio.ready_gpio = COLIBRI320_READY_GPIO; + colibri_pcmcia_gpios[RESET].gpio = COLIBRI320_RESET_GPIO; + colibri_pcmcia_gpios[PPEN].gpio = COLIBRI320_PPEN_GPIO; + colibri_pcmcia_gpios[BVD1].gpio = COLIBRI320_BVD1_GPIO; + colibri_pcmcia_gpios[BVD2].gpio = COLIBRI320_BVD2_GPIO; + colibri_pcmcia_gpios[DETECT].gpio = COLIBRI320_DETECT_GPIO; + colibri_pcmcia_gpios[READY].gpio = COLIBRI320_READY_GPIO; } ret = platform_device_add_data(colibri_pcmcia_device, diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c index 6fb6f7f0672e..69f73670949a 100644 --- a/drivers/pcmcia/pxa2xx_palmld.c +++ b/drivers/pcmcia/pxa2xx_palmld.c @@ -4,7 +4,7 @@ * Driver for Palm LifeDrive PCMCIA * * Copyright (C) 2006 Alex Osborne <ato@meshy.org> - * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -20,49 +20,27 @@ #include <mach/palmld.h> #include "soc_common.h" +static struct gpio palmld_pcmcia_gpios[] = { + { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" }, + { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, + { GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, +}; + static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR"); - if (ret) - goto err1; - ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0); - if (ret) - goto err2; - - ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1); - if (ret) - goto err3; - - ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY"); - if (ret) - goto err3; - ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY); - if (ret) - goto err4; + ret = gpio_request_array(palmld_pcmcia_gpios, + ARRAY_SIZE(palmld_pcmcia_gpios)); skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY); - return 0; -err4: - gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); -err3: - gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET); -err2: - gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER); -err1: return ret; } static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(GPIO_NR_PALMLD_PCMCIA_READY); - gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET); - gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER); + gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios)); } static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt, diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c index 459a232d66be..d0ad6a76bbde 100644 --- a/drivers/pcmcia/pxa2xx_palmtc.c +++ b/drivers/pcmcia/pxa2xx_palmtc.c @@ -4,7 +4,7 @@ * Driver for Palm Tungsten|C PCMCIA * * Copyright (C) 2008 Alex Osborne <ato@meshy.org> - * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -21,79 +21,30 @@ #include <mach/palmtc.h> #include "soc_common.h" +static struct gpio palmtc_pcmcia_gpios[] = { + { GPIO_NR_PALMTC_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, + { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, + { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" }, + { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, + { GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, + { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" }, +}; + static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1"); - if (ret) - goto err1; - ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0); - if (ret) - goto err2; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0); - if (ret) - goto err3; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3"); - if (ret) - goto err3; - ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0); - if (ret) - goto err4; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST"); - if (ret) - goto err4; - ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1); - if (ret) - goto err5; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY"); - if (ret) - goto err5; - ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY); - if (ret) - goto err6; - - ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY"); - if (ret) - goto err6; - ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY); - if (ret) - goto err7; + ret = gpio_request_array(palmtc_pcmcia_gpios, + ARRAY_SIZE(palmtc_pcmcia_gpios)); skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY); - return 0; -err7: - gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); -err6: - gpio_free(GPIO_NR_PALMTC_PCMCIA_READY); -err5: - gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET); -err4: - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3); -err3: - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2); -err2: - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1); -err1: return ret; } static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY); - gpio_free(GPIO_NR_PALMTC_PCMCIA_READY); - gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET); - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3); - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2); - gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1); + gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios)); } static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt, diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c index b07b247a399f..1a2580450402 100644 --- a/drivers/pcmcia/pxa2xx_palmtx.c +++ b/drivers/pcmcia/pxa2xx_palmtx.c @@ -3,7 +3,7 @@ * * Driver for Palm T|X PCMCIA * - * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -13,67 +13,34 @@ #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/gpio.h> #include <asm/mach-types.h> - -#include <mach/gpio.h> #include <mach/palmtx.h> - #include "soc_common.h" +static struct gpio palmtx_pcmcia_gpios[] = { + { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" }, + { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" }, + { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" }, + { GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" }, +}; + static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { int ret; - ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1"); - if (ret) - goto err1; - ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0); - if (ret) - goto err2; - - ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2"); - if (ret) - goto err2; - ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0); - if (ret) - goto err3; - - ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST"); - if (ret) - goto err3; - ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1); - if (ret) - goto err4; - - ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY"); - if (ret) - goto err4; - ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY); - if (ret) - goto err5; + ret = gpio_request_array(palmtx_pcmcia_gpios, + ARRAY_SIZE(palmtx_pcmcia_gpios)); skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY); - return 0; -err5: - gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); -err4: - gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET); -err3: - gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2); -err2: - gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1); -err1: return ret; } static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(GPIO_NR_PALMTX_PCMCIA_READY); - gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET); - gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2); - gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1); + gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios)); } static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt, diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c index 55627eccee8e..435002dfc3ca 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c @@ -3,8 +3,7 @@ * * Driver for Voipac PXA270 PCMCIA and CF sockets * - * Copyright (C) 2010 - * Marek Vasut <marek.vasut@gmail.com> + * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,6 +21,19 @@ #include "soc_common.h" +static struct gpio vpac270_pcmcia_gpios[] = { + { GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" }, + { GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" }, + { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" }, + { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" }, +}; + +static struct gpio vpac270_cf_gpios[] = { + { GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" }, + { GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" }, + { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" }, +}; + static struct pcmcia_irqs cd_irqs[] = { { .sock = 0, @@ -40,96 +52,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) int ret; if (skt->nr == 0) { - ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD"); - if (ret) - goto err1; - ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD); - if (ret) - goto err2; - - ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY"); - if (ret) - goto err2; - ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY); - if (ret) - goto err3; - - ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN"); - if (ret) - goto err3; - ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0); - if (ret) - goto err4; - - ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET"); - if (ret) - goto err4; - ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0); - if (ret) - goto err5; + ret = gpio_request_array(vpac270_pcmcia_gpios, + ARRAY_SIZE(vpac270_pcmcia_gpios)); skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY); - return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); - -err5: - gpio_free(GPIO11_VPAC270_PCMCIA_RESET); -err4: - gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); -err3: - gpio_free(GPIO35_VPAC270_PCMCIA_RDY); -err2: - gpio_free(GPIO84_VPAC270_PCMCIA_CD); -err1: - return ret; - + if (!ret) + ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1); } else { - ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD"); - if (ret) - goto err6; - ret = gpio_direction_input(GPIO17_VPAC270_CF_CD); - if (ret) - goto err7; - - ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY"); - if (ret) - goto err7; - ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY); - if (ret) - goto err8; - - ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET"); - if (ret) - goto err8; - ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0); - if (ret) - goto err9; + ret = gpio_request_array(vpac270_cf_gpios, + ARRAY_SIZE(vpac270_cf_gpios)); skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY); - return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); - -err9: - gpio_free(GPIO16_VPAC270_CF_RESET); -err8: - gpio_free(GPIO12_VPAC270_CF_RDY); -err7: - gpio_free(GPIO17_VPAC270_CF_CD); -err6: - return ret; - + if (!ret) + ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1); } + + return ret; } static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) { - gpio_free(GPIO11_VPAC270_PCMCIA_RESET); - gpio_free(GPIO107_VPAC270_PCMCIA_PPEN); - gpio_free(GPIO35_VPAC270_PCMCIA_RDY); - gpio_free(GPIO84_VPAC270_PCMCIA_CD); - gpio_free(GPIO16_VPAC270_CF_RESET); - gpio_free(GPIO12_VPAC270_CF_RDY); - gpio_free(GPIO17_VPAC270_CF_CD); + if (skt->nr == 0) + gpio_request_array(vpac270_pcmcia_gpios, + ARRAY_SIZE(vpac270_pcmcia_gpios)); + else + gpio_request_array(vpac270_cf_gpios, + ARRAY_SIZE(vpac270_cf_gpios)); } static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index b86bc328463b..332a2c4a891c 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -319,7 +319,7 @@ static irqreturn_t mrst_rtc_irq(int irq, void *p) return IRQ_NONE; } -static int __init +static int __devinit vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq) { int retval = 0; @@ -391,7 +391,7 @@ static void rtc_mrst_do_shutdown(void) spin_unlock_irq(&rtc_lock); } -static void __exit rtc_mrst_do_remove(struct device *dev) +static void __devexit rtc_mrst_do_remove(struct device *dev) { struct mrst_rtc *mrst = dev_get_drvdata(dev); struct resource *iomem; @@ -500,14 +500,14 @@ static inline int mrst_poweroff(struct device *dev) #endif -static int __init vrtc_mrst_platform_probe(struct platform_device *pdev) +static int __devinit vrtc_mrst_platform_probe(struct platform_device *pdev) { return vrtc_mrst_do_probe(&pdev->dev, platform_get_resource(pdev, IORESOURCE_MEM, 0), platform_get_irq(pdev, 0)); } -static int __exit vrtc_mrst_platform_remove(struct platform_device *pdev) +static int __devexit vrtc_mrst_platform_remove(struct platform_device *pdev) { rtc_mrst_do_remove(&pdev->dev); return 0; @@ -525,7 +525,7 @@ MODULE_ALIAS("platform:vrtc_mrst"); static struct platform_driver vrtc_mrst_platform_driver = { .probe = vrtc_mrst_platform_probe, - .remove = __exit_p(vrtc_mrst_platform_remove), + .remove = __devexit_p(vrtc_mrst_platform_remove), .shutdown = vrtc_mrst_platform_shutdown, .driver = { .name = (char *) driver_name, diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index 0571ef9639cb..9f4b58b7daad 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c @@ -138,6 +138,7 @@ #include <linux/spinlock.h> #include <linux/stat.h> #include <linux/bitops.h> +#include <linux/delay.h> #include <asm/io.h> #include <asm/system.h> diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h index df36a421e675..5b934851efa8 100644 --- a/drivers/sh/intc/internals.h +++ b/drivers/sh/intc/internals.h @@ -86,7 +86,7 @@ enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */ static inline struct intc_desc_int *get_intc_desc(unsigned int irq) { - struct irq_chip *chip = get_irq_chip(irq); + struct irq_chip *chip = irq_get_chip(irq); return container_of(chip, struct intc_desc_int, chip); } @@ -103,7 +103,7 @@ static inline void activate_irq(int irq) set_irq_flags(irq, IRQF_VALID); #else /* same effect on other architectures */ - set_irq_noprobe(irq); + irq_set_noprobe(irq); #endif } diff --git a/drivers/staging/altera-stapl/altera-jtag.c b/drivers/staging/altera-stapl/altera-jtag.c index 6b633b179a7e..876308858b82 100644 --- a/drivers/staging/altera-stapl/altera-jtag.c +++ b/drivers/staging/altera-stapl/altera-jtag.c @@ -23,6 +23,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/delay.h> #include <linux/firmware.h> #include <linux/slab.h> #include <staging/altera.h> diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 428f4fe0b5f7..0ad32888091c 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -95,6 +95,7 @@ static void n_tty_set_room(struct tty_struct *tty) { /* tty->read_cnt is not read locked ? */ int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; + int old_left; /* * If we are doing input canonicalization, and there are no @@ -104,7 +105,12 @@ static void n_tty_set_room(struct tty_struct *tty) */ if (left <= 0) left = tty->icanon && !tty->canon_data; + old_left = tty->receive_room; tty->receive_room = left; + + /* Did this open up the receive buffer? We may need to flip */ + if (left && !old_left) + schedule_work(&tty->buf.work); } static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index e1aee37270f5..80484af781e1 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1506,7 +1506,7 @@ config SERIAL_BCM63XX_CONSOLE config SERIAL_GRLIB_GAISLER_APBUART tristate "GRLIB APBUART serial support" - depends on OF + depends on OF && SPARC select SERIAL_CORE ---help--- Add support for the GRLIB APBUART serial port. diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c index 1ab999b04ef3..19a943693e4c 100644 --- a/drivers/tty/serial/apbuart.c +++ b/drivers/tty/serial/apbuart.c @@ -555,10 +555,9 @@ static struct uart_driver grlib_apbuart_driver = { static int __devinit apbuart_probe(struct platform_device *op) { - int i = -1; + int i; struct uart_port *port = NULL; - i = 0; for (i = 0; i < grlib_apbuart_port_nr; i++) { if (op->dev.of_node == grlib_apbuart_nodes[i]) break; @@ -566,6 +565,7 @@ static int __devinit apbuart_probe(struct platform_device *op) port = &grlib_apbuart_ports[i]; port->dev = &op->dev; + port->irq = op->archdata.irqs[0]; uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port); @@ -598,24 +598,12 @@ static struct platform_driver grlib_apbuart_of_driver = { static int grlib_apbuart_configure(void) { - struct device_node *np, *rp; - const u32 *prop; - int freq_khz, line = 0; - - /* Get bus frequency */ - rp = of_find_node_by_path("/"); - if (!rp) - return -ENODEV; - rp = of_get_next_child(rp, NULL); - if (!rp) - return -ENODEV; - prop = of_get_property(rp, "clock-frequency", NULL); - if (!prop) - return -ENODEV; - freq_khz = *prop; + struct device_node *np; + int line = 0; for_each_matching_node(np, apbuart_match) { - const int *irqs, *ampopts; + const int *ampopts; + const u32 *freq_hz; const struct amba_prom_registers *regs; struct uart_port *port; unsigned long addr; @@ -623,11 +611,11 @@ static int grlib_apbuart_configure(void) ampopts = of_get_property(np, "ampopts", NULL); if (ampopts && (*ampopts == 0)) continue; /* Ignore if used by another OS instance */ - - irqs = of_get_property(np, "interrupts", NULL); regs = of_get_property(np, "reg", NULL); + /* Frequency of APB Bus is frequency of UART */ + freq_hz = of_get_property(np, "freq", NULL); - if (!irqs || !regs) + if (!regs || !freq_hz || (*freq_hz == 0)) continue; grlib_apbuart_nodes[line] = np; @@ -638,12 +626,12 @@ static int grlib_apbuart_configure(void) port->mapbase = addr; port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map)); - port->irq = *irqs; + port->irq = 0; port->iotype = UPIO_MEM; port->ops = &grlib_apbuart_ops; port->flags = UPF_BOOT_AUTOCONF; port->line = line; - port->uartclk = freq_khz * 1000; + port->uartclk = *freq_hz; port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line); line++; diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index b9451219528b..f1a7918d71aa 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -442,10 +442,8 @@ static void flush_to_ldisc(struct work_struct *work) line discipline as we want to empty the queue */ if (test_bit(TTY_FLUSHPENDING, &tty->flags)) break; - if (!tty->receive_room || seen_tail) { - schedule_work(&tty->buf.work); + if (!tty->receive_room || seen_tail) break; - } if (count > tty->receive_room) count = tty->receive_room; char_buf = head->char_buf_ptr + head->read; diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index b37f92cb71bc..444b60aa15e9 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -139,24 +139,6 @@ static const char ep0name [] = "ep0"; static void pxa25x_ep_fifo_flush (struct usb_ep *ep); static void nuke (struct pxa25x_ep *, int status); -/* one GPIO should be used to detect VBUS from the host */ -static int is_vbus_present(void) -{ - struct pxa2xx_udc_mach_info *mach = the_controller->mach; - - if (gpio_is_valid(mach->gpio_vbus)) { - int value = gpio_get_value(mach->gpio_vbus); - - if (mach->gpio_vbus_inverted) - return !value; - else - return !!value; - } - if (mach->udc_is_connected) - return mach->udc_is_connected(); - return 1; -} - /* one GPIO should control a D+ pullup, so host sees this device (or not) */ static void pullup_off(void) { @@ -1055,7 +1037,7 @@ udc_seq_show(struct seq_file *m, void *_d) "%s version: %s\nGadget driver: %s\nHost %s\n\n", driver_name, DRIVER_VERSION SIZE_STR "(pio)", dev->driver ? dev->driver->driver.name : "(none)", - is_vbus_present() ? "full speed" : "disconnected"); + dev->gadget.speed == USB_SPEED_FULL ? "full speed" : "disconnected"); /* registers for device and ep0 */ seq_printf(m, @@ -1094,7 +1076,7 @@ udc_seq_show(struct seq_file *m, void *_d) (tmp & UDCCFR_ACM) ? " acm" : ""); } - if (!is_vbus_present() || !dev->driver) + if (dev->gadget.speed != USB_SPEED_FULL || !dev->driver) goto done; seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n", @@ -1435,14 +1417,6 @@ lubbock_vbus_irq(int irq, void *_dev) #endif -static irqreturn_t udc_vbus_irq(int irq, void *_dev) -{ - struct pxa25x_udc *dev = _dev; - - pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present()); - return IRQ_HANDLED; -} - /*-------------------------------------------------------------------------*/ @@ -1766,12 +1740,9 @@ pxa25x_udc_irq(int irq, void *_dev) if (unlikely(udccr & UDCCR_SUSIR)) { udc_ack_int_UDCCR(UDCCR_SUSIR); handled = 1; - DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present() - ? "" : "+disconnect"); + DBG(DBG_VERBOSE, "USB suspend\n"); - if (!is_vbus_present()) - stop_activity(dev, dev->driver); - else if (dev->gadget.speed != USB_SPEED_UNKNOWN + if (dev->gadget.speed != USB_SPEED_UNKNOWN && dev->driver && dev->driver->suspend) dev->driver->suspend(&dev->gadget); @@ -1786,8 +1757,7 @@ pxa25x_udc_irq(int irq, void *_dev) if (dev->gadget.speed != USB_SPEED_UNKNOWN && dev->driver - && dev->driver->resume - && is_vbus_present()) + && dev->driver->resume) dev->driver->resume(&dev->gadget); } @@ -2137,7 +2107,7 @@ static struct pxa25x_udc memory = { static int __init pxa25x_udc_probe(struct platform_device *pdev) { struct pxa25x_udc *dev = &memory; - int retval, vbus_irq, irq; + int retval, irq; u32 chiprev; /* insist on Intel/ARM/XScale */ @@ -2199,19 +2169,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->transceiver = otg_get_transceiver(); - if (gpio_is_valid(dev->mach->gpio_vbus)) { - if ((retval = gpio_request(dev->mach->gpio_vbus, - "pxa25x_udc GPIO VBUS"))) { - dev_dbg(&pdev->dev, - "can't get vbus gpio %d, err: %d\n", - dev->mach->gpio_vbus, retval); - goto err_gpio_vbus; - } - gpio_direction_input(dev->mach->gpio_vbus); - vbus_irq = gpio_to_irq(dev->mach->gpio_vbus); - } else - vbus_irq = 0; - if (gpio_is_valid(dev->mach->gpio_pullup)) { if ((retval = gpio_request(dev->mach->gpio_pullup, "pca25x_udc GPIO PULLUP"))) { @@ -2237,7 +2194,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) udc_disable(dev); udc_reinit(dev); - dev->vbus = !!is_vbus_present(); + dev->vbus = 0; /* irq setup after old hardware state is cleaned up */ retval = request_irq(irq, pxa25x_udc_irq, @@ -2273,22 +2230,10 @@ lubbock_fail0: } } else #endif - if (vbus_irq) { - retval = request_irq(vbus_irq, udc_vbus_irq, - IRQF_DISABLED | IRQF_SAMPLE_RANDOM | - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - driver_name, dev); - if (retval != 0) { - pr_err("%s: can't get irq %i, err %d\n", - driver_name, vbus_irq, retval); - goto err_vbus_irq; - } - } create_debug_files(dev); return 0; - err_vbus_irq: #ifdef CONFIG_ARCH_LUBBOCK free_irq(LUBBOCK_USB_DISC_IRQ, dev); err_irq_lub: @@ -2298,9 +2243,6 @@ lubbock_fail0: if (gpio_is_valid(dev->mach->gpio_pullup)) gpio_free(dev->mach->gpio_pullup); err_gpio_pullup: - if (gpio_is_valid(dev->mach->gpio_vbus)) - gpio_free(dev->mach->gpio_vbus); - err_gpio_vbus: if (dev->transceiver) { otg_put_transceiver(dev->transceiver); dev->transceiver = NULL; @@ -2337,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) free_irq(LUBBOCK_USB_IRQ, dev); } #endif - if (gpio_is_valid(dev->mach->gpio_vbus)) { - free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); - gpio_free(dev->mach->gpio_vbus); - } if (gpio_is_valid(dev->mach->gpio_pullup)) gpio_free(dev->mach->gpio_pullup); diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index d2c019637e45..ba0d28727ccb 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -106,7 +106,7 @@ static void mct_u232_break_ctl(struct tty_struct *tty, int break_state); static int mct_u232_tiocmget(struct tty_struct *tty); static int mct_u232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int mct_u232_ioctl(struct tty_struct *tty, struct file *file, +static int mct_u232_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg); static int mct_u232_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount); @@ -874,7 +874,7 @@ static void mct_u232_unthrottle(struct tty_struct *tty) } } -static int mct_u232_ioctl(struct tty_struct *tty, struct file *file, +static int mct_u232_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { DEFINE_WAIT(wait); diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 201f6096844b..a1dd4d4fa192 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -413,7 +413,7 @@ static int opticon_tiocmget(struct tty_struct *tty) return result; } -static int opticon_tiocmset(struct tty_struct *tty, struct file *file, +static int opticon_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { struct usb_serial_port *port = tty->driver_data; diff --git a/drivers/video/fb-puv3.c b/drivers/video/fb-puv3.c index dbd2dc4745d1..27f2c57e06e9 100644 --- a/drivers/video/fb-puv3.c +++ b/drivers/video/fb-puv3.c @@ -13,7 +13,6 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> -#include <linux/vmalloc.h> #include <linux/platform_device.h> #include <linux/clk.h> #include <linux/fb.h> @@ -531,7 +530,7 @@ static int unifb_set_par(struct fb_info *info) return -EINVAL; } - writel(PKUNITY_UNIGFX_MMAP_BASE, UDE_FSA); + writel(info->fix.smem_start, UDE_FSA); writel(info->var.yres, UDE_LS); writel(get_line_length(info->var.xres, info->var.bits_per_pixel) >> 3, UDE_PS); @@ -680,13 +679,27 @@ static int unifb_probe(struct platform_device *dev) struct fb_info *info; u32 unifb_regs[UNIFB_REGS_NUM]; int retval = -ENOMEM; - struct resource *iomem, *mapmem; + struct resource *iomem; + void *videomemory; + + videomemory = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP, + get_order(UNIFB_MEMSIZE)); + if (!videomemory) + goto err; + + memset(videomemory, 0, UNIFB_MEMSIZE); + + unifb_fix.smem_start = virt_to_phys(videomemory); + unifb_fix.smem_len = UNIFB_MEMSIZE; + + iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); + unifb_fix.mmio_start = iomem->start; info = framebuffer_alloc(sizeof(u32)*256, &dev->dev); if (!info) goto err; - info->screen_base = (char __iomem *)KUSER_UNIGFX_BASE; + info->screen_base = (char __iomem *)videomemory; info->fbops = &unifb_ops; retval = fb_find_mode(&info->var, info, NULL, @@ -695,13 +708,6 @@ static int unifb_probe(struct platform_device *dev) if (!retval || (retval == 4)) info->var = unifb_default; - iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); - unifb_fix.mmio_start = iomem->start; - - mapmem = platform_get_resource(dev, IORESOURCE_MEM, 1); - unifb_fix.smem_start = mapmem->start; - unifb_fix.smem_len = UNIFB_MEMSIZE; - info->fix = unifb_fix; info->pseudo_palette = info->par; info->par = NULL; diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 825b665245bb..a2e5b5100ab4 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb) static void overlay1fb_disable(struct pxafb_layer *ofb) { - uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5); + uint32_t lccr5; + + if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN)) + return; + + lccr5 = lcd_readl(ofb->fbi, LCCR5); lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN); @@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb) static void overlay2fb_disable(struct pxafb_layer *ofb) { - uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5); + uint32_t lccr5; + + if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN)) + return; + + lccr5 = lcd_readl(ofb->fbi, LCCR5); lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN); @@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user) if (user == 0) return -ENODEV; - /* allow only one user at a time */ - if (atomic_inc_and_test(&ofb->usage)) - return -EBUSY; + if (ofb->usage++ == 0) + /* unblank the base framebuffer */ + fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); - /* unblank the base framebuffer */ - fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK); return 0; } @@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user) { struct pxafb_layer *ofb = (struct pxafb_layer*) info; - atomic_dec(&ofb->usage); - ofb->ops->disable(ofb); + if (ofb->usage == 1) { + ofb->ops->disable(ofb); + ofb->fb.var.height = -1; + ofb->fb.var.width = -1; + ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0; + ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0; - free_pages_exact(ofb->video_mem, ofb->video_mem_size); - ofb->video_mem = NULL; - ofb->video_mem_size = 0; + ofb->usage--; + } return 0; } @@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var, int xpos, ypos, pfor, bpp; xpos = NONSTD_TO_XPOS(var->nonstd); - ypos = NONSTD_TO_XPOS(var->nonstd); + ypos = NONSTD_TO_YPOS(var->nonstd); pfor = NONSTD_TO_PFOR(var->nonstd); bpp = pxafb_var_to_bpp(var); @@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var, return 0; } -static int overlayfb_map_video_memory(struct pxafb_layer *ofb) +static int overlayfb_check_video_memory(struct pxafb_layer *ofb) { struct fb_var_screeninfo *var = &ofb->fb.var; int pfor = NONSTD_TO_PFOR(var->nonstd); @@ -812,27 +823,11 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb) size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual); - /* don't re-allocate if the original video memory is enough */ if (ofb->video_mem) { if (ofb->video_mem_size >= size) return 0; - - free_pages_exact(ofb->video_mem, ofb->video_mem_size); } - - ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); - if (ofb->video_mem == NULL) - return -ENOMEM; - - ofb->video_mem_phys = virt_to_phys(ofb->video_mem); - ofb->video_mem_size = size; - - mutex_lock(&ofb->fb.mm_lock); - ofb->fb.fix.smem_start = ofb->video_mem_phys; - ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual; - mutex_unlock(&ofb->fb.mm_lock); - ofb->fb.screen_base = ofb->video_mem; - return 0; + return -EINVAL; } static int overlayfb_set_par(struct fb_info *info) @@ -841,13 +836,13 @@ static int overlayfb_set_par(struct fb_info *info) struct fb_var_screeninfo *var = &info->var; int xpos, ypos, pfor, bpp, ret; - ret = overlayfb_map_video_memory(ofb); + ret = overlayfb_check_video_memory(ofb); if (ret) return ret; bpp = pxafb_var_to_bpp(var); xpos = NONSTD_TO_XPOS(var->nonstd); - ypos = NONSTD_TO_XPOS(var->nonstd); + ypos = NONSTD_TO_YPOS(var->nonstd); pfor = NONSTD_TO_PFOR(var->nonstd); ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) | @@ -891,7 +886,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi, ofb->id = id; ofb->ops = &ofb_ops[id]; - atomic_set(&ofb->usage, 0); + ofb->usage = 0; ofb->fbi = fbi; init_completion(&ofb->branch_done); } @@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void) return 0; } -static int __devinit pxafb_overlay_init(struct pxafb_info *fbi) +static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb, + struct pxafb_layer *ofb) +{ + /* We assume that user will use at most video_mem_size for overlay fb, + * anyway, it's useless to use 16bpp main plane and 24bpp overlay + */ + ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size), + GFP_KERNEL | __GFP_ZERO); + if (ofb->video_mem == NULL) + return -ENOMEM; + + ofb->video_mem_phys = virt_to_phys(ofb->video_mem); + ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size); + + mutex_lock(&ofb->fb.mm_lock); + ofb->fb.fix.smem_start = ofb->video_mem_phys; + ofb->fb.fix.smem_len = pxafb->video_mem_size; + mutex_unlock(&ofb->fb.mm_lock); + + ofb->fb.screen_base = ofb->video_mem; + + return 0; +} + +static void __devinit pxafb_overlay_init(struct pxafb_info *fbi) { int i, ret; if (!pxafb_overlay_supported()) - return 0; + return; for (i = 0; i < 2; i++) { - init_pxafb_overlay(fbi, &fbi->overlay[i], i); - ret = register_framebuffer(&fbi->overlay[i].fb); + struct pxafb_layer *ofb = &fbi->overlay[i]; + init_pxafb_overlay(fbi, ofb, i); + ret = register_framebuffer(&ofb->fb); if (ret) { dev_err(fbi->dev, "failed to register overlay %d\n", i); - return ret; + continue; } + ret = pxafb_overlay_map_video_memory(fbi, ofb); + if (ret) { + dev_err(fbi->dev, + "failed to map video memory for overlay %d\n", + i); + unregister_framebuffer(&ofb->fb); + continue; + } + ofb->registered = 1; } /* mask all IU/BS/EOF/SOF interrupts */ lcd_writel(fbi, LCCR5, ~0); - /* place overlay(s) on top of base */ - fbi->lccr0 |= LCCR0_OUC; pr_info("PXA Overlay driver loaded successfully!\n"); - return 0; } static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) @@ -936,8 +962,15 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi) if (!pxafb_overlay_supported()) return; - for (i = 0; i < 2; i++) - unregister_framebuffer(&fbi->overlay[i].fb); + for (i = 0; i < 2; i++) { + struct pxafb_layer *ofb = &fbi->overlay[i]; + if (ofb->registered) { + if (ofb->video_mem) + free_pages_exact(ofb->video_mem, + ofb->video_mem_size); + unregister_framebuffer(&ofb->fb); + } + } } #else static inline void pxafb_overlay_init(struct pxafb_info *fbi) {} @@ -1368,7 +1401,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) || (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) || (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) || - (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])) + ((fbi->lccr0 & LCCR0_SDS) && + (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))) pxafb_schedule_work(fbi, C_REENABLE); return 0; @@ -1420,7 +1454,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB); lcd_writel(fbi, FDADR0, fbi->fdadr[0]); - lcd_writel(fbi, FDADR1, fbi->fdadr[1]); + if (fbi->lccr0 & LCCR0_SDS) + lcd_writel(fbi, FDADR1, fbi->fdadr[1]); lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB); } @@ -1613,7 +1648,8 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) switch (val) { case CPUFREQ_PRECHANGE: - set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); + if (!fbi->overlay[0].usage && !fbi->overlay[1].usage) + set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); break; case CPUFREQ_POSTCHANGE: @@ -1806,6 +1842,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) pxafb_decode_mach_info(fbi, inf); +#ifdef CONFIG_FB_PXA_OVERLAY + /* place overlay(s) on top of base */ + if (pxafb_overlay_supported()) + fbi->lccr0 |= LCCR0_OUC; +#endif + init_waitqueue_head(&fbi->ctrlr_wait); INIT_WORK(&fbi->task, pxafb_task); mutex_init(&fbi->ctrlr_lock); diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h index 2353521c5c8c..26ba9fa3f737 100644 --- a/drivers/video/pxafb.h +++ b/drivers/video/pxafb.h @@ -92,7 +92,8 @@ struct pxafb_layer_ops { struct pxafb_layer { struct fb_info fb; int id; - atomic_t usage; + int registered; + uint32_t usage; uint32_t control[2]; struct pxafb_layer_ops *ops; diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index d47ce8307854..3458b5725540 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1284,6 +1284,8 @@ struct btrfs_root { #define BTRFS_INODE_DIRSYNC (1 << 10) #define BTRFS_INODE_COMPRESS (1 << 11) +#define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) + /* some macros to generate set/get funcs for the struct fields. This * assumes there is a lefoo_to_cpu for every type, so lets make a simple * one for u8: @@ -2359,6 +2361,8 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); int btrfs_find_orphan_roots(struct btrfs_root *tree_root); int btrfs_set_root_node(struct btrfs_root_item *item, struct extent_buffer *node); +void btrfs_check_and_init_root_item(struct btrfs_root_item *item); + /* dir-item.c */ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, const char *name, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index d7a7315bd031..8f1d44ba332f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1275,8 +1275,10 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, root->commit_root = btrfs_root_node(root); BUG_ON(!root->node); out: - if (location->objectid != BTRFS_TREE_LOG_OBJECTID) + if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { root->ref_cows = 1; + btrfs_check_and_init_root_item(&root->root_item); + } return root; } diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 656bc0a892b1..e621ea54a3fd 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -906,7 +906,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, unsigned long last_index; size_t num_written = 0; int nrptrs; - int ret; + int ret = 0; nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE, PAGE_CACHE_SIZE / diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 0037427d8a9d..f561c953205b 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -24,6 +24,7 @@ #include "free-space-cache.h" #include "transaction.h" #include "disk-io.h" +#include "extent_io.h" #define BITS_PER_BITMAP (PAGE_CACHE_SIZE * 8) #define MAX_CACHE_BYTES_PER_GIG (32 * 1024) @@ -81,6 +82,8 @@ struct inode *lookup_free_space_inode(struct btrfs_root *root, return ERR_PTR(-ENOENT); } + inode->i_mapping->flags &= ~__GFP_FS; + spin_lock(&block_group->lock); if (!root->fs_info->closing) { block_group->inode = igrab(inode); @@ -222,6 +225,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, u64 num_entries; u64 num_bitmaps; u64 generation; + u64 used = btrfs_block_group_used(&block_group->item); u32 cur_crc = ~(u32)0; pgoff_t index = 0; unsigned long first_page_offset; @@ -467,6 +471,17 @@ next: index++; } + spin_lock(&block_group->tree_lock); + if (block_group->free_space != (block_group->key.offset - used - + block_group->bytes_super)) { + spin_unlock(&block_group->tree_lock); + printk(KERN_ERR "block group %llu has an wrong amount of free " + "space\n", block_group->key.objectid); + ret = 0; + goto free_cache; + } + spin_unlock(&block_group->tree_lock); + ret = 1; out: kfree(checksums); @@ -495,8 +510,11 @@ int btrfs_write_out_cache(struct btrfs_root *root, struct list_head *pos, *n; struct page *page; struct extent_state *cached_state = NULL; + struct btrfs_free_cluster *cluster = NULL; + struct extent_io_tree *unpin = NULL; struct list_head bitmap_list; struct btrfs_key key; + u64 start, end, len; u64 bytes = 0; u32 *crc, *checksums; pgoff_t index = 0, last_index = 0; @@ -505,6 +523,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, int entries = 0; int bitmaps = 0; int ret = 0; + bool next_page = false; root = root->fs_info->tree_root; @@ -551,6 +570,18 @@ int btrfs_write_out_cache(struct btrfs_root *root, */ first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); + /* Get the cluster for this block_group if it exists */ + if (!list_empty(&block_group->cluster_list)) + cluster = list_entry(block_group->cluster_list.next, + struct btrfs_free_cluster, + block_group_list); + + /* + * We shouldn't have switched the pinned extents yet so this is the + * right one + */ + unpin = root->fs_info->pinned_extents; + /* * Lock all pages first so we can lock the extent safely. * @@ -580,6 +611,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, lock_extent_bits(&BTRFS_I(inode)->io_tree, 0, i_size_read(inode) - 1, 0, &cached_state, GFP_NOFS); + /* + * When searching for pinned extents, we need to start at our start + * offset. + */ + start = block_group->key.objectid; + /* Write out the extent entries */ do { struct btrfs_free_space_entry *entry; @@ -587,6 +624,8 @@ int btrfs_write_out_cache(struct btrfs_root *root, unsigned long offset = 0; unsigned long start_offset = 0; + next_page = false; + if (index == 0) { start_offset = first_page_offset; offset = start_offset; @@ -598,7 +637,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, entry = addr + start_offset; memset(addr, 0, PAGE_CACHE_SIZE); - while (1) { + while (node && !next_page) { struct btrfs_free_space *e; e = rb_entry(node, struct btrfs_free_space, offset_index); @@ -614,12 +653,49 @@ int btrfs_write_out_cache(struct btrfs_root *root, entry->type = BTRFS_FREE_SPACE_EXTENT; } node = rb_next(node); - if (!node) - break; + if (!node && cluster) { + node = rb_first(&cluster->root); + cluster = NULL; + } offset += sizeof(struct btrfs_free_space_entry); if (offset + sizeof(struct btrfs_free_space_entry) >= PAGE_CACHE_SIZE) + next_page = true; + entry++; + } + + /* + * We want to add any pinned extents to our free space cache + * so we don't leak the space + */ + while (!next_page && (start < block_group->key.objectid + + block_group->key.offset)) { + ret = find_first_extent_bit(unpin, start, &start, &end, + EXTENT_DIRTY); + if (ret) { + ret = 0; + break; + } + + /* This pinned extent is out of our range */ + if (start >= block_group->key.objectid + + block_group->key.offset) break; + + len = block_group->key.objectid + + block_group->key.offset - start; + len = min(len, end + 1 - start); + + entries++; + entry->offset = cpu_to_le64(start); + entry->bytes = cpu_to_le64(len); + entry->type = BTRFS_FREE_SPACE_EXTENT; + + start = end + 1; + offset += sizeof(struct btrfs_free_space_entry); + if (offset + sizeof(struct btrfs_free_space_entry) >= + PAGE_CACHE_SIZE) + next_page = true; entry++; } *crc = ~(u32)0; @@ -650,7 +726,7 @@ int btrfs_write_out_cache(struct btrfs_root *root, page_cache_release(page); index++; - } while (node); + } while (node || next_page); /* Write out the bitmaps */ list_for_each_safe(pos, n, &bitmap_list) { diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 93c28a1d6bdc..65413394daef 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -112,6 +112,7 @@ static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode, u64 start, size_t size, size_t compressed_size, + int compress_type, struct page **compressed_pages) { struct btrfs_key key; @@ -126,12 +127,9 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, size_t cur_size = size; size_t datasize; unsigned long offset; - int compress_type = BTRFS_COMPRESS_NONE; - if (compressed_size && compressed_pages) { - compress_type = root->fs_info->compress_type; + if (compressed_size && compressed_pages) cur_size = compressed_size; - } path = btrfs_alloc_path(); if (!path) @@ -221,7 +219,7 @@ fail: static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode, u64 start, u64 end, - size_t compressed_size, + size_t compressed_size, int compress_type, struct page **compressed_pages) { u64 isize = i_size_read(inode); @@ -254,7 +252,7 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, inline_len = min_t(u64, isize, actual_end); ret = insert_inline_extent(trans, root, inode, start, inline_len, compressed_size, - compressed_pages); + compress_type, compressed_pages); BUG_ON(ret); btrfs_delalloc_release_metadata(inode, end + 1 - start); btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0); @@ -433,12 +431,13 @@ again: * to make an uncompressed inline extent. */ ret = cow_file_range_inline(trans, root, inode, - start, end, 0, NULL); + start, end, 0, 0, NULL); } else { /* try making a compressed inline extent */ ret = cow_file_range_inline(trans, root, inode, start, end, - total_compressed, pages); + total_compressed, + compress_type, pages); } if (ret == 0) { /* @@ -792,7 +791,7 @@ static noinline int cow_file_range(struct inode *inode, if (start == 0) { /* lets try to make an inline extent */ ret = cow_file_range_inline(trans, root, inode, - start, end, 0, NULL); + start, end, 0, 0, NULL); if (ret == 0) { extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, @@ -2222,8 +2221,6 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) insert = 1; #endif insert = 1; - } else { - WARN_ON(!BTRFS_I(inode)->orphan_meta_reserved); } if (!BTRFS_I(inode)->orphan_meta_reserved) { @@ -2537,8 +2534,6 @@ static void btrfs_read_locked_inode(struct inode *inode) BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); alloc_group_block = btrfs_inode_block_group(leaf, inode_item); - if (location.objectid == BTRFS_FREE_SPACE_OBJECTID) - inode->i_mapping->flags &= ~__GFP_FS; /* * try to precache a NULL acl entry for files that don't have @@ -6960,8 +6955,10 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, * should cover the worst case number of items we'll modify. */ trans = btrfs_start_transaction(root, 20); - if (IS_ERR(trans)) - return PTR_ERR(trans); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out_notrans; + } btrfs_set_trans_block_group(trans, new_dir); @@ -7061,7 +7058,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, } out_fail: btrfs_end_transaction_throttle(trans, root); - +out_notrans: if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) up_read(&root->fs_info->subvol_sem); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7c07fe26b7cf..cfc264fefdb0 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -373,6 +373,10 @@ static noinline int create_subvol(struct btrfs_root *root, inode_item->nbytes = cpu_to_le64(root->leafsize); inode_item->mode = cpu_to_le32(S_IFDIR | 0755); + root_item.flags = 0; + root_item.byte_limit = 0; + inode_item->flags = cpu_to_le64(BTRFS_INODE_ROOT_ITEM_INIT); + btrfs_set_root_bytenr(&root_item, leaf->start); btrfs_set_root_generation(&root_item, trans->transid); btrfs_set_root_level(&root_item, 0); @@ -2436,8 +2440,10 @@ static noinline long btrfs_ioctl_start_sync(struct file *file, void __user *argp return PTR_ERR(trans); transid = trans->transid; ret = btrfs_commit_transaction_async(trans, root, 0); - if (ret) + if (ret) { + btrfs_end_transaction(trans, root); return ret; + } if (argp) if (copy_to_user(argp, &transid, sizeof(transid))) diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 29b2d7c930eb..6928bff62daa 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -473,3 +473,21 @@ again: btrfs_free_path(path); return 0; } + +/* + * Old btrfs forgets to init root_item->flags and root_item->byte_limit + * for subvolumes. To work around this problem, we steal a bit from + * root_item->inode_item->flags, and use it to indicate if those fields + * have been properly initialized. + */ +void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item) +{ + u64 inode_flags = le64_to_cpu(root_item->inode.flags); + + if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) { + inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT; + root_item->inode.flags = cpu_to_le64(inode_flags); + root_item->flags = 0; + root_item->byte_limit = 0; + } +} diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 2edfc039f098..58e7de9cc90c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -644,6 +644,7 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) { struct btrfs_root *root = btrfs_sb(vfs->mnt_sb); struct btrfs_fs_info *info = root->fs_info; + char *compress_type; if (btrfs_test_opt(root, DEGRADED)) seq_puts(seq, ",degraded"); @@ -662,8 +663,16 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) if (info->thread_pool_size != min_t(unsigned long, num_online_cpus() + 2, 8)) seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); - if (btrfs_test_opt(root, COMPRESS)) - seq_puts(seq, ",compress"); + if (btrfs_test_opt(root, COMPRESS)) { + if (info->compress_type == BTRFS_COMPRESS_ZLIB) + compress_type = "zlib"; + else + compress_type = "lzo"; + if (btrfs_test_opt(root, FORCE_COMPRESS)) + seq_printf(seq, ",compress-force=%s", compress_type); + else + seq_printf(seq, ",compress=%s", compress_type); + } if (btrfs_test_opt(root, NOSSD)) seq_puts(seq, ",nossd"); if (btrfs_test_opt(root, SSD_SPREAD)) @@ -678,6 +687,12 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) seq_puts(seq, ",discard"); if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) seq_puts(seq, ",noacl"); + if (btrfs_test_opt(root, SPACE_CACHE)) + seq_puts(seq, ",space_cache"); + if (btrfs_test_opt(root, CLEAR_CACHE)) + seq_puts(seq, ",clear_cache"); + if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) + seq_puts(seq, ",user_subvol_rm_allowed"); return 0; } diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index ce48eb59d615..5b158da7e0bb 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -197,6 +197,7 @@ again: ret = join_transaction(root); if (ret < 0) { + kmem_cache_free(btrfs_trans_handle_cachep, h); if (type != TRANS_JOIN_NOLOCK) mutex_unlock(&root->fs_info->trans_mutex); return ERR_PTR(ret); @@ -975,6 +976,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, record_root_in_trans(trans, root); btrfs_set_root_last_snapshot(&root->root_item, trans->transid); memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); + btrfs_check_and_init_root_item(new_root_item); root_flags = btrfs_root_flags(new_root_item); if (pending->readonly) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index a1ee8fa3a8e7..f60b07b0feb0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -3215,9 +3215,15 @@ void ceph_mdsc_destroy(struct ceph_fs_client *fsc) { struct ceph_mds_client *mdsc = fsc->mdsc; + dout("mdsc_destroy %p\n", mdsc); ceph_mdsc_stop(mdsc); + + /* flush out any connection work with references to us */ + ceph_msgr_flush(); + fsc->mdsc = NULL; kfree(mdsc); + dout("mdsc_destroy %p done\n", mdsc); } diff --git a/fs/ceph/super.c b/fs/ceph/super.c index a9e78b4a258c..f2f77fd3c14c 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -353,7 +353,7 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt) if (opt->name) seq_printf(m, ",name=%s", opt->name); - if (opt->secret) + if (opt->key) seq_puts(m, ",secret=<hidden>"); if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT) diff --git a/fs/inode.c b/fs/inode.c index 5f4e11aaeb5c..33c963d08ab4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -125,6 +125,14 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(inode_wb_list_lock); static DECLARE_RWSEM(iprune_sem); /* + * Empty aops. Can be used for the cases where the user does not + * define any of the address_space operations. + */ +const struct address_space_operations empty_aops = { +}; +EXPORT_SYMBOL(empty_aops); + +/* * Statistics gathering.. */ struct inodes_stat_t inodes_stat; @@ -176,7 +184,6 @@ int proc_nr_inodes(ctl_table *table, int write, */ int inode_init_always(struct super_block *sb, struct inode *inode) { - static const struct address_space_operations empty_aops; static const struct inode_operations empty_iops; static const struct file_operations empty_fops; struct address_space *const mapping = &inode->i_data; diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 93589fccdd97..397e73258631 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c @@ -72,10 +72,9 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) /* * check to see if the page is mapped already (no holes) */ - if (PageMappedToDisk(page)) { - unlock_page(page); + if (PageMappedToDisk(page)) goto mapped; - } + if (page_has_buffers(page)) { struct buffer_head *bh, *head; int fully_mapped = 1; @@ -90,7 +89,6 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) if (fully_mapped) { SetPageMappedToDisk(page); - unlock_page(page); goto mapped; } } @@ -105,16 +103,17 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) return VM_FAULT_SIGBUS; ret = block_page_mkwrite(vma, vmf, nilfs_get_block); - if (unlikely(ret)) { + if (ret != VM_FAULT_LOCKED) { nilfs_transaction_abort(inode->i_sb); return ret; } + nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits)); nilfs_transaction_commit(inode->i_sb); mapped: SetPageChecked(page); wait_on_page_writeback(page); - return 0; + return VM_FAULT_LOCKED; } static const struct vm_operations_struct nilfs_file_vm_ops = { diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 856e8e4e0b74..a8dd344303cb 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h @@ -114,19 +114,19 @@ enum { * Macros to check inode numbers */ #define NILFS_MDT_INO_BITS \ - ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO | \ - 1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO | \ - 1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO)) + ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO | \ + 1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO | \ + 1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO)) #define NILFS_SYS_INO_BITS \ - ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS) + ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS) #define NILFS_FIRST_INO(sb) (((struct the_nilfs *)sb->s_fs_info)->ns_first_ino) #define NILFS_MDT_INODE(sb, ino) \ - ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino)))) + ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino)))) #define NILFS_VALID_INODE(sb, ino) \ - ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino)))) + ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino)))) /** * struct nilfs_transaction_info: context information for synchronization @@ -285,7 +285,7 @@ extern void nilfs_destroy_inode(struct inode *); extern void nilfs_error(struct super_block *, const char *, const char *, ...) __attribute__ ((format (printf, 3, 4))); extern void nilfs_warning(struct super_block *, const char *, const char *, ...) - __attribute__ ((format (printf, 3, 4))); + __attribute__ ((format (printf, 3, 4))); extern struct nilfs_super_block * nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **); extern int nilfs_store_magic_and_option(struct super_block *, diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index 4d2a1ee0eb47..1168059c7efd 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c @@ -500,7 +500,7 @@ void nilfs_mapping_init(struct address_space *mapping, mapping_set_gfp_mask(mapping, GFP_NOFS); mapping->assoc_mapping = NULL; mapping->backing_dev_info = bdi; - mapping->a_ops = NULL; + mapping->a_ops = &empty_aops; } /* diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index a91b69a6a291..0348d0c8f65e 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -198,6 +198,7 @@ static void inotify_free_group_priv(struct fsnotify_group *group) idr_for_each(&group->inotify_data.idr, idr_callback, group); idr_remove_all(&group->inotify_data.idr); idr_destroy(&group->inotify_data.idr); + atomic_dec(&group->inotify_data.user->inotify_devs); free_uid(group->inotify_data.user); } diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index bd46e7c8a0ef..8445fbc8985c 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -290,7 +290,6 @@ static int inotify_fasync(int fd, struct file *file, int on) static int inotify_release(struct inode *ignored, struct file *file) { struct fsnotify_group *group = file->private_data; - struct user_struct *user = group->inotify_data.user; pr_debug("%s: group=%p\n", __func__, group); @@ -299,8 +298,6 @@ static int inotify_release(struct inode *ignored, struct file *file) /* free this group, matching get was inotify_init->fsnotify_obtain_group */ fsnotify_put_group(group); - atomic_dec(&user->inotify_devs); - return 0; } @@ -697,7 +694,7 @@ retry: return ret; } -static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsigned int max_events) +static struct fsnotify_group *inotify_new_group(unsigned int max_events) { struct fsnotify_group *group; @@ -710,8 +707,14 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign spin_lock_init(&group->inotify_data.idr_lock); idr_init(&group->inotify_data.idr); group->inotify_data.last_wd = 0; - group->inotify_data.user = user; group->inotify_data.fa = NULL; + group->inotify_data.user = get_current_user(); + + if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > + inotify_max_user_instances) { + fsnotify_put_group(group); + return ERR_PTR(-EMFILE); + } return group; } @@ -721,7 +724,6 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign SYSCALL_DEFINE1(inotify_init1, int, flags) { struct fsnotify_group *group; - struct user_struct *user; int ret; /* Check the IN_* constants for consistency. */ @@ -731,31 +733,16 @@ SYSCALL_DEFINE1(inotify_init1, int, flags) if (flags & ~(IN_CLOEXEC | IN_NONBLOCK)) return -EINVAL; - user = get_current_user(); - if (unlikely(atomic_read(&user->inotify_devs) >= - inotify_max_user_instances)) { - ret = -EMFILE; - goto out_free_uid; - } - /* fsnotify_obtain_group took a reference to group, we put this when we kill the file in the end */ - group = inotify_new_group(user, inotify_max_queued_events); - if (IS_ERR(group)) { - ret = PTR_ERR(group); - goto out_free_uid; - } - - atomic_inc(&user->inotify_devs); + group = inotify_new_group(inotify_max_queued_events); + if (IS_ERR(group)) + return PTR_ERR(group); ret = anon_inode_getfd("inotify", &inotify_fops, group, O_RDONLY | flags); - if (ret >= 0) - return ret; + if (ret < 0) + fsnotify_put_group(group); - fsnotify_put_group(group); - atomic_dec(&user->inotify_devs); -out_free_uid: - free_uid(user); return ret; } diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index c74400f88fe0..3299f469e712 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c @@ -56,6 +56,7 @@ */ #include "ubifs.h" +#include <linux/fs.h> #include <linux/slab.h> #include <linux/xattr.h> #include <linux/posix_acl_xattr.h> @@ -80,7 +81,6 @@ enum { }; static const struct inode_operations none_inode_operations; -static const struct address_space_operations none_address_operations; static const struct file_operations none_file_operations; /** @@ -130,7 +130,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, } /* Re-define all operations to be "nothing" */ - inode->i_mapping->a_ops = &none_address_operations; + inode->i_mapping->a_ops = &empty_aops; inode->i_op = &none_inode_operations; inode->i_fop = &none_file_operations; diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 11014302c9ca..5f821dbc0579 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -479,7 +479,6 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) break; if (IS_SYNC(inode) && (inode->i_state & I_DIRTY)) ufs_sync_inode (inode); - blk_flush_plug(current); yield(); } diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index f2d2faf4d9ae..e5a3f5880001 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -194,6 +194,13 @@ extern void warn_slowpath_null(const char *file, const int line); #ifdef CONFIG_SMP # define WARN_ON_SMP(x) WARN_ON(x) #else +/* + * Use of ({0;}) because WARN_ON_SMP(x) may be used either as + * a stand alone line statement or as a condition in an if () + * statement. + * A simple "0" would cause gcc to give a "statement has no effect" + * warning. + */ # define WARN_ON_SMP(x) ({0;}) #endif diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 60edf9be31e5..aaec09713bee 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -778,6 +778,7 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern u8 *drm_find_cea_extension(struct edid *edid); extern bool drm_detect_hdmi_monitor(struct edid *edid); extern bool drm_detect_monitor_audio(struct edid *edid); extern int drm_mode_page_flip_ioctl(struct drm_device *dev, diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 820ee9029482..816e30cbd968 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -472,6 +472,8 @@ {0x1002, 0x9803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9804, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9806, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9807, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0, 0, 0} #define r128_PCI_IDS \ diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index 50852aad260a..a6bd117c9ff1 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -158,9 +158,9 @@ struct ttm_tt; * the object is destroyed. * @event_queue: Queue for processes waiting on buffer object status change. * @mem: structure describing current placement. - * @persistant_swap_storage: Usually the swap storage is deleted for buffers + * @persistent_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistant shmem object. + * holds a pointer to a persistent shmem object. * @ttm: TTM structure holding system pages. * @evicted: Whether the object was evicted without user-space knowing. * @cpu_writes: For synchronization. Number of cpu writers. @@ -221,7 +221,7 @@ struct ttm_buffer_object { */ struct ttm_mem_reg mem; - struct file *persistant_swap_storage; + struct file *persistent_swap_storage; struct ttm_tt *ttm; bool evicted; @@ -459,9 +459,9 @@ extern void ttm_bo_synccpu_write_release(struct ttm_buffer_object *bo); * user buffer object. * @interruptible: If needing to sleep to wait for GPU resources, * sleep interruptible. - * @persistant_swap_storage: Usually the swap storage is deleted for buffers + * @persistent_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistant shmem object. Typically, this would + * holds a pointer to a persistent shmem object. Typically, this would * point to the shmem object backing a GEM object if TTM is used to back a * GEM user interface. * @acc_size: Accounted size for this object. @@ -490,7 +490,7 @@ extern int ttm_bo_init(struct ttm_bo_device *bdev, uint32_t page_alignment, unsigned long buffer_start, bool interrubtible, - struct file *persistant_swap_storage, + struct file *persistent_swap_storage, size_t acc_size, void (*destroy) (struct ttm_buffer_object *)); /** @@ -506,9 +506,9 @@ extern int ttm_bo_init(struct ttm_bo_device *bdev, * user buffer object. * @interruptible: If needing to sleep while waiting for GPU resources, * sleep interruptible. - * @persistant_swap_storage: Usually the swap storage is deleted for buffers + * @persistent_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member - * holds a pointer to a persistant shmem object. Typically, this would + * holds a pointer to a persistent shmem object. Typically, this would * point to the shmem object backing a GEM object if TTM is used to back a * GEM user interface. * @p_bo: On successful completion *p_bo points to the created object. @@ -528,7 +528,7 @@ extern int ttm_bo_create(struct ttm_bo_device *bdev, uint32_t page_alignment, unsigned long buffer_start, bool interruptible, - struct file *persistant_swap_storage, + struct file *persistent_swap_storage, struct ttm_buffer_object **p_bo); /** diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index efed0820d9fa..960b52181d4e 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -122,7 +122,7 @@ struct ttm_backend { #define TTM_PAGE_FLAG_USER_DIRTY (1 << 2) #define TTM_PAGE_FLAG_WRITE (1 << 3) #define TTM_PAGE_FLAG_SWAPPED (1 << 4) -#define TTM_PAGE_FLAG_PERSISTANT_SWAP (1 << 5) +#define TTM_PAGE_FLAG_PERSISTENT_SWAP (1 << 5) #define TTM_PAGE_FLAG_ZERO_ALLOC (1 << 6) #define TTM_PAGE_FLAG_DMA32 (1 << 7) @@ -714,7 +714,7 @@ extern void ttm_tt_cache_flush(struct page *pages[], unsigned long num_pages); */ extern int ttm_tt_set_placement_caching(struct ttm_tt *ttm, uint32_t placement); extern int ttm_tt_swapout(struct ttm_tt *ttm, - struct file *persistant_swap_storage); + struct file *persistent_swap_storage); /* * ttm_bo.c diff --git a/include/keys/ceph-type.h b/include/keys/ceph-type.h new file mode 100644 index 000000000000..f69c4ac197a0 --- /dev/null +++ b/include/keys/ceph-type.h @@ -0,0 +1,8 @@ +#ifndef _KEYS_CEPH_TYPE_H +#define _KEYS_CEPH_TYPE_H + +#include <linux/key.h> + +extern struct key_type key_type_ceph; + +#endif diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 475f8c42c0e9..381f4cec8260 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -443,6 +443,7 @@ void atm_dev_signal_change(struct atm_dev *dev, char signal); void vcc_insert_socket(struct sock *sk); +void atm_dev_release_vccs(struct atm_dev *dev); /* * This is approximately the algorithm used by alloc_skb. diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 16a902f099ac..32176cc8e715 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1206,6 +1206,7 @@ struct blk_integrity { struct kobject kobj; }; +extern bool blk_integrity_is_initialized(struct gendisk *); extern int blk_integrity_register(struct gendisk *, struct blk_integrity *); extern void blk_integrity_unregister(struct gendisk *); extern int blk_integrity_compare(struct gendisk *, struct gendisk *); @@ -1262,6 +1263,7 @@ queue_max_integrity_segments(struct request_queue *q) #define queue_max_integrity_segments(a) (0) #define blk_integrity_merge_rq(a, b, c) (0) #define blk_integrity_merge_bio(a, b, c) (0) +#define blk_integrity_is_initialized(a) (0) #endif /* CONFIG_BLK_DEV_INTEGRITY */ diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h index 7fff521d7eb5..aa13392a7efb 100644 --- a/include/linux/ceph/auth.h +++ b/include/linux/ceph/auth.h @@ -67,12 +67,12 @@ struct ceph_auth_client { bool negotiating; /* true if negotiating protocol */ const char *name; /* entity name */ u64 global_id; /* our unique id in system */ - const char *secret; /* our secret key */ + const struct ceph_crypto_key *key; /* our secret key */ unsigned want_keys; /* which services we want */ }; extern struct ceph_auth_client *ceph_auth_init(const char *name, - const char *secret); + const struct ceph_crypto_key *key); extern void ceph_auth_destroy(struct ceph_auth_client *ac); extern void ceph_auth_reset(struct ceph_auth_client *ac); diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 0d2e0fffb470..6365f041745b 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -61,7 +61,7 @@ struct ceph_options { pointer type of args */ int num_mon; char *name; - char *secret; + struct ceph_crypto_key *key; }; /* diff --git a/include/linux/connector.h b/include/linux/connector.h index bcafc942e5e4..7c60d0942adb 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -88,8 +88,6 @@ struct cn_queue_dev { atomic_t refcnt; unsigned char name[CN_CBQ_NAMELEN]; - struct workqueue_struct *cn_queue; - struct list_head queue_list; spinlock_t queue_lock; @@ -101,20 +99,13 @@ struct cn_callback_id { struct cb_id id; }; -struct cn_callback_data { - struct sk_buff *skb; - void (*callback) (struct cn_msg *, struct netlink_skb_parms *); - - void *free; -}; - struct cn_callback_entry { struct list_head callback_entry; - struct work_struct work; + atomic_t refcnt; struct cn_queue_dev *pdev; struct cn_callback_id id; - struct cn_callback_data data; + void (*callback) (struct cn_msg *, struct netlink_skb_parms *); u32 seq, group; }; @@ -138,13 +129,12 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); +void cn_queue_release_callback(struct cn_callback_entry *); struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *); void cn_queue_free_dev(struct cn_queue_dev *dev); int cn_cb_equal(struct cb_id *, struct cb_id *); -void cn_queue_wrapper(struct work_struct *work); - #endif /* __KERNEL__ */ #endif /* __CONNECTOR_H */ diff --git a/include/linux/elevator.h b/include/linux/elevator.h index d93efcc44570..21a8ebf2dc3a 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -101,7 +101,6 @@ extern void elv_dispatch_sort(struct request_queue *, struct request *); extern void elv_dispatch_add_tail(struct request_queue *, struct request *); extern void elv_add_request(struct request_queue *, struct request *, int); extern void __elv_add_request(struct request_queue *, struct request *, int); -extern void elv_insert(struct request_queue *, struct request *, int); extern int elv_merge(struct request_queue *, struct request **, struct bio *); extern int elv_try_merge(struct request *, struct bio *); extern void elv_merge_requests(struct request_queue *, struct request *, diff --git a/include/linux/fs.h b/include/linux/fs.h index 52f283c1edb2..1b95af37e3b3 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -613,6 +613,8 @@ struct address_space_operations { int (*error_remove_page)(struct address_space *, struct page *); }; +extern const struct address_space_operations empty_aops; + /* * pagecache_write_begin/pagecache_write_end must be used by general code * to write into the pagecache. diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 59b72ca1c5d1..943c9b53695c 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -338,14 +338,6 @@ static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long /* IRQ wakeup (PM) control: */ extern int irq_set_irq_wake(unsigned int irq, unsigned int on); -#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT -/* Please do not use: Use the replacement functions instead */ -static inline int set_irq_wake(unsigned int irq, unsigned int on) -{ - return irq_set_irq_wake(irq, on); -} -#endif - static inline int enable_irq_wake(unsigned int irq) { return irq_set_irq_wake(irq, 1); diff --git a/include/linux/irq.h b/include/linux/irq.h index 2a375a72ce3c..09a308072f56 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -64,13 +64,6 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set) * IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context * IRQ_NESTED_TRHEAD - Interrupt nests into another thread - * - * Deprecated bits. They are kept updated as long as - * CONFIG_GENERIC_HARDIRQS_NO_COMPAT is not set. Will go away soon. These bits - * are internal state of the core code and if you really need to acces - * them then talk to the genirq maintainer instead of hacking - * something weird. - * */ enum { IRQ_TYPE_NONE = 0x00000000, diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 03e8e8dbc577..c2478a342cd7 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -208,6 +208,7 @@ int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, unsigned long long *crash_size, unsigned long long *crash_base); int crash_shrink_memory(unsigned long new_size); size_t crash_get_memory_size(void); +void crash_free_reserved_phys_range(unsigned long begin, unsigned long end); #else /* !CONFIG_KEXEC */ struct pt_regs; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 5eeb2cd3631c..0249fe7e3872 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2598,8 +2598,8 @@ static inline int dev_ethtool_get_settings(struct net_device *dev, static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev) { - if (dev->hw_features & NETIF_F_RXCSUM) - return !!(dev->features & NETIF_F_RXCSUM); + if (dev->features & NETIF_F_RXCSUM) + return 1; if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum) return 0; return dev->ethtool_ops->get_rx_csum(dev); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 11fd38151cc9..4e2c9150a785 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -518,7 +518,7 @@ #define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 #define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 #define PCI_DEVICE_ID_AMD_15H_NB_F3 0x1603 -#define PCI_DEVICE_ID_AMD_15H_NB_LINK 0x1604 +#define PCI_DEVICE_ID_AMD_15H_NB_F4 0x1604 #define PCI_DEVICE_ID_AMD_CNB17H_F3 0x1703 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 311b4dc785a1..04d75a8a20ee 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1086,7 +1086,7 @@ void perf_event_task_sched_out(struct task_struct *task, struct task_struct *nex { perf_sw_event(PERF_COUNT_SW_CONTEXT_SWITCHES, 1, 1, NULL, 0); - COND_STMT(&perf_sched_events, __perf_event_task_sched_out(task, next)); + __perf_event_task_sched_out(task, next); } extern void perf_event_mmap(struct vm_area_struct *vma); diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index af5614856285..ff422d2b7f90 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -339,6 +339,12 @@ extern int rcu_my_thread_group_empty(void); ((typeof(*p) __force __kernel *)(p)); \ }) +#define __rcu_access_index(p, space) \ + ({ \ + typeof(p) _________p1 = ACCESS_ONCE(p); \ + rcu_dereference_sparse(p, space); \ + (_________p1); \ + }) #define __rcu_dereference_index_check(p, c) \ ({ \ typeof(p) _________p1 = ACCESS_ONCE(p); \ @@ -429,6 +435,20 @@ extern int rcu_my_thread_group_empty(void); #define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/ /** + * rcu_access_index() - fetch RCU index with no dereferencing + * @p: The index to read + * + * Return the value of the specified RCU-protected index, but omit the + * smp_read_barrier_depends() and keep the ACCESS_ONCE(). This is useful + * when the value of this index is accessed, but the index is not + * dereferenced, for example, when testing an RCU-protected index against + * -1. Although rcu_access_index() may also be used in cases where + * update-side locks prevent the value of the index from changing, you + * should instead use rcu_dereference_index_protected() for this use case. + */ +#define rcu_access_index(p) __rcu_access_index((p), __rcu) + +/** * rcu_dereference_index_check() - rcu_dereference for indices with debug checking * @p: The pointer to read, prior to dereferencing * @c: The conditions under which the dereference will take place diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 239083bfea13..d9e52fa2416d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -126,7 +126,7 @@ struct sk_buff; * GRO uses frags we allocate at least 16 regardless of page size. */ #if (65536/PAGE_SIZE + 2) < 16 -#define MAX_SKB_FRAGS 16 +#define MAX_SKB_FRAGS 16UL #else #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2) #endif diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 44842c8d38c0..3c7329b8ea0e 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -97,11 +97,14 @@ struct driver_info { #define FLAG_LINK_INTR 0x0800 /* updates link (carrier) status */ +#define FLAG_POINTTOPOINT 0x1000 /* possibly use "usb%d" names */ + /* * Indicates to usbnet, that USB driver accumulates multiple IP packets. * Affects statistic (counters) and short packet handling. */ #define FLAG_MULTI_PACKET 0x1000 +#define FLAG_RX_ASSEMBLE 0x2000 /* rx packets may span >1 frames */ /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); @@ -172,7 +175,9 @@ struct cdc_state { }; extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *); +extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *); extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *); +extern void usbnet_cdc_status(struct usbnet *, struct urb *); /* CDC and RNDIS support the same host-chosen packet filters for IN transfers */ #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index ec6acf2f1c0b..2c0d309c7381 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -84,6 +84,8 @@ enum { HCI_SERVICE_CACHE, HCI_LINK_KEYS, HCI_DEBUG_KEYS, + + HCI_RESET, }; /* HCI ioctl defines */ diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 04977eefb0ee..fccc2180c61b 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -286,5 +286,21 @@ static inline void ipv6_ib_mc_map(const struct in6_addr *addr, buf[9] = broadcast[9]; memcpy(buf + 10, addr->s6_addr + 6, 10); } + +static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr, + const unsigned char *broadcast, char *buf) +{ + if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) { + memcpy(buf, broadcast, 4); + } else { + /* v4mapped? */ + if ((addr->s6_addr32[0] | addr->s6_addr32[1] | + (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0) + return -EINVAL; + memcpy(buf, &addr->s6_addr32[3], 4); + } + return 0; +} + #endif #endif diff --git a/include/net/ip.h b/include/net/ip.h index a4f631108c54..7c416583b710 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -339,6 +339,14 @@ static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, ch buf[16] = addr & 0x0f; } +static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf) +{ + if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) + memcpy(buf, broadcast, 4); + else + memcpy(buf, &naddr, sizeof(naddr)); +} + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #include <linux/ipv6.h> #endif diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index cc9185ca8fd1..0f6e60a9c308 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -422,7 +422,7 @@ struct sctp_cookie { __u32 adaptation_ind; __u8 auth_random[sizeof(sctp_paramhdr_t) + SCTP_AUTH_RANDOM_LENGTH]; - __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS + 2]; + __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2]; __u8 auth_chunks[sizeof(sctp_paramhdr_t) + SCTP_AUTH_MAX_CHUNKS]; /* This is a shim for my peer's INIT packet, followed by diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 979ed84e07d6..ddc2b3d6be03 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -45,25 +45,25 @@ /* platform domain */ #define SND_SOC_DAPM_INPUT(wname) \ { .id = snd_soc_dapm_input, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0} + .num_kcontrols = 0, .reg = SND_SOC_NOPM } #define SND_SOC_DAPM_OUTPUT(wname) \ { .id = snd_soc_dapm_output, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0} + .num_kcontrols = 0, .reg = SND_SOC_NOPM } #define SND_SOC_DAPM_MIC(wname, wevent) \ { .id = snd_soc_dapm_mic, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ + .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} #define SND_SOC_DAPM_HP(wname, wevent) \ { .id = snd_soc_dapm_hp, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ + .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} #define SND_SOC_DAPM_SPK(wname, wevent) \ { .id = snd_soc_dapm_spk, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ + .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} #define SND_SOC_DAPM_LINE(wname, wevent) \ { .id = snd_soc_dapm_line, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ + .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} /* path domain */ @@ -189,11 +189,11 @@ /* events that are pre and post DAPM */ #define SND_SOC_DAPM_PRE(wname, wevent) \ { .id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ + .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD} #define SND_SOC_DAPM_POST(wname, wevent) \ { .id = snd_soc_dapm_post, .name = wname, .kcontrols = NULL, \ - .num_kcontrols = 0, .event = wevent, \ + .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD} /* stream domain */ diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index a69c333f78e4..c574f9a12c48 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -10,9 +10,6 @@ menu "IRQ subsystem" config GENERIC_HARDIRQS def_bool y -config GENERIC_HARDIRQS_NO_COMPAT - bool - # Options selectable by the architecture code # Make sparse irq Kconfig switch below available diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 616ec1c6b06f..1dafc8652bd8 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -514,7 +514,7 @@ void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc) } while ((desc->istate & IRQS_PENDING) && !irqd_irq_disabled(&desc->irq_data)); -out_unlock: +out_eoi: chip->irq_eoi(&desc->irq_data); raw_spin_unlock(&desc->lock); } diff --git a/kernel/kexec.c b/kernel/kexec.c index ec19b92c7ebd..4e240a378df6 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1099,7 +1099,8 @@ size_t crash_get_memory_size(void) return size; } -static void free_reserved_phys_range(unsigned long begin, unsigned long end) +void __weak crash_free_reserved_phys_range(unsigned long begin, + unsigned long end) { unsigned long addr; @@ -1135,7 +1136,7 @@ int crash_shrink_memory(unsigned long new_size) start = roundup(start, PAGE_SIZE); end = roundup(start + new_size, PAGE_SIZE); - free_reserved_phys_range(end, crashk_res.end); + crash_free_reserved_phys_range(end, crashk_res.end); if ((start == end) && (crashk_res.parent != NULL)) release_resource(&crashk_res); diff --git a/kernel/perf_event.c b/kernel/perf_event.c index c75925c4d1e2..27960f114efd 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -145,8 +145,8 @@ static struct srcu_struct pmus_srcu; */ int sysctl_perf_event_paranoid __read_mostly = 1; -/* Minimum for 128 pages + 1 for the user control page */ -int sysctl_perf_event_mlock __read_mostly = 516; /* 'free' kb per user */ +/* Minimum for 512 kiB + 1 user control page */ +int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ /* * max perf event sample rate @@ -6531,6 +6531,11 @@ SYSCALL_DEFINE5(perf_event_open, goto err_alloc; } + if (task) { + put_task_struct(task); + task = NULL; + } + /* * Look up the group leader (we will attach this event to it): */ diff --git a/kernel/sched.c b/kernel/sched.c index f592ce6f8616..a8845516ace6 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5011,6 +5011,17 @@ recheck: return -EINVAL; } + /* + * If not changing anything there's no need to proceed further: + */ + if (unlikely(policy == p->policy && (!rt_policy(policy) || + param->sched_priority == p->rt_priority))) { + + __task_rq_unlock(rq); + raw_spin_unlock_irqrestore(&p->pi_lock, flags); + return 0; + } + #ifdef CONFIG_RT_GROUP_SCHED if (user) { /* diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 3f7ec9e27ee1..c7ec5c8e7b44 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -22,6 +22,7 @@ #include <linux/latencytop.h> #include <linux/sched.h> +#include <linux/cpumask.h> /* * Targeted preemption latency for CPU-bound tasks: @@ -3850,8 +3851,8 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle) interval = msecs_to_jiffies(interval); if (unlikely(!interval)) interval = 1; - if (interval > HZ*NR_CPUS/10) - interval = HZ*NR_CPUS/10; + if (interval > HZ*num_online_cpus()/10) + interval = HZ*num_online_cpus()/10; need_serialize = sd->flags & SD_SERIALIZE; diff --git a/kernel/signal.c b/kernel/signal.c index 1186cf7fac77..dc17929ab78a 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -226,7 +226,7 @@ static inline void print_dropped_signal(int sig) /* * allocate a new signal queue record * - this may be called without locks if and only if t == current, otherwise an - * appopriate lock must be held to stop the target task from exiting + * appropriate lock must be held to stop the target task from exiting */ static struct sigqueue * __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimit) @@ -375,15 +375,15 @@ int unhandled_signal(struct task_struct *tsk, int sig) return !tracehook_consider_fatal_signal(tsk, sig); } - -/* Notify the system that a driver wants to block all signals for this +/* + * Notify the system that a driver wants to block all signals for this * process, and wants to be notified if any signals at all were to be * sent/acted upon. If the notifier routine returns non-zero, then the * signal will be acted upon after all. If the notifier routine returns 0, * then then signal will be blocked. Only one block per process is * allowed. priv is a pointer to private data that the notifier routine - * can use to determine if the signal should be blocked or not. */ - + * can use to determine if the signal should be blocked or not. + */ void block_all_signals(int (*notifier)(void *priv), void *priv, sigset_t *mask) { @@ -434,9 +434,10 @@ still_pending: copy_siginfo(info, &first->info); __sigqueue_free(first); } else { - /* Ok, it wasn't in the queue. This must be - a fast-pathed signal or we must have been - out of queue space. So zero out the info. + /* + * Ok, it wasn't in the queue. This must be + * a fast-pathed signal or we must have been + * out of queue space. So zero out the info. */ info->si_signo = sig; info->si_errno = 0; @@ -468,7 +469,7 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, } /* - * Dequeue a signal and return the element to the caller, which is + * Dequeue a signal and return the element to the caller, which is * expected to free it. * * All callers have to hold the siglock. @@ -490,7 +491,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) * itimers are process shared and we restart periodic * itimers in the signal delivery path to prevent DoS * attacks in the high resolution timer case. This is - * compliant with the old way of self restarting + * compliant with the old way of self-restarting * itimers, as the SIGALRM is a legacy signal and only * queued once. Changing the restart behaviour to * restart the timer in the signal dequeue path is @@ -923,14 +924,15 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, if (info == SEND_SIG_FORCED) goto out_set; - /* Real-time signals must be queued if sent by sigqueue, or - some other real-time mechanism. It is implementation - defined whether kill() does so. We attempt to do so, on - the principle of least surprise, but since kill is not - allowed to fail with EAGAIN when low on memory we just - make sure at least one signal gets delivered and don't - pass on the info struct. */ - + /* + * Real-time signals must be queued if sent by sigqueue, or + * some other real-time mechanism. It is implementation + * defined whether kill() does so. We attempt to do so, on + * the principle of least surprise, but since kill is not + * allowed to fail with EAGAIN when low on memory we just + * make sure at least one signal gets delivered and don't + * pass on the info struct. + */ if (sig < SIGRTMIN) override_rlimit = (is_si_special(info) || info->si_code >= 0); else @@ -1201,8 +1203,7 @@ retry: return error; } -int -kill_proc_info(int sig, struct siginfo *info, pid_t pid) +int kill_proc_info(int sig, struct siginfo *info, pid_t pid) { int error; rcu_read_lock(); @@ -1299,8 +1300,7 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid) * These are for backward compatibility with the rest of the kernel source. */ -int -send_sig_info(int sig, struct siginfo *info, struct task_struct *p) +int send_sig_info(int sig, struct siginfo *info, struct task_struct *p) { /* * Make sure legacy kernel users don't send in bad values @@ -1368,7 +1368,7 @@ EXPORT_SYMBOL(kill_pid); * These functions support sending signals using preallocated sigqueue * structures. This is needed "because realtime applications cannot * afford to lose notifications of asynchronous events, like timer - * expirations or I/O completions". In the case of Posix Timers + * expirations or I/O completions". In the case of POSIX Timers * we allocate the sigqueue structure from the timer_create. If this * allocation fails we are able to report the failure to the application * with an EAGAIN error. @@ -1553,7 +1553,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why) info.si_signo = SIGCHLD; info.si_errno = 0; /* - * see comment in do_notify_parent() abot the following 3 lines + * see comment in do_notify_parent() about the following 4 lines */ rcu_read_lock(); info.si_pid = task_pid_nr_ns(tsk, parent->nsproxy->pid_ns); @@ -1611,7 +1611,7 @@ static inline int may_ptrace_stop(void) } /* - * Return nonzero if there is a SIGKILL that should be waking us up. + * Return non-zero if there is a SIGKILL that should be waking us up. * Called with the siglock held. */ static int sigkill_pending(struct task_struct *tsk) @@ -1735,7 +1735,7 @@ void ptrace_notify(int exit_code) /* * This performs the stopping for SIGSTOP and other stop signals. * We have to stop all threads in the thread group. - * Returns nonzero if we've actually stopped and released the siglock. + * Returns non-zero if we've actually stopped and released the siglock. * Returns zero if we didn't stop and still hold the siglock. */ static int do_signal_stop(int signr) @@ -1823,10 +1823,12 @@ static int ptrace_signal(int signr, siginfo_t *info, current->exit_code = 0; - /* Update the siginfo structure if the signal has - changed. If the debugger wanted something - specific in the siginfo structure then it should - have updated *info via PTRACE_SETSIGINFO. */ + /* + * Update the siginfo structure if the signal has + * changed. If the debugger wanted something + * specific in the siginfo structure then it should + * have updated *info via PTRACE_SETSIGINFO. + */ if (signr != info->si_signo) { info->si_signo = signr; info->si_errno = 0; @@ -2034,7 +2036,8 @@ void exit_signals(struct task_struct *tsk) if (!signal_pending(tsk)) goto out; - /* It could be that __group_complete_signal() choose us to + /* + * It could be that __group_complete_signal() choose us to * notify about group-wide signal. Another thread should be * woken now to take the signal since we will not. */ @@ -2072,6 +2075,9 @@ EXPORT_SYMBOL(unblock_all_signals); * System call entry points. */ +/** + * sys_restart_syscall - restart a system call + */ SYSCALL_DEFINE0(restart_syscall) { struct restart_block *restart = ¤t_thread_info()->restart_block; @@ -2125,6 +2131,13 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset) return error; } +/** + * sys_rt_sigprocmask - change the list of currently blocked signals + * @how: whether to add, remove, or set signals + * @set: stores pending signals + * @oset: previous value of signal mask if non-null + * @sigsetsize: size of sigset_t type + */ SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, set, sigset_t __user *, oset, size_t, sigsetsize) { @@ -2183,8 +2196,14 @@ long do_sigpending(void __user *set, unsigned long sigsetsize) out: return error; -} +} +/** + * sys_rt_sigpending - examine a pending signal that has been raised + * while blocked + * @set: stores pending signals + * @sigsetsize: size of sigset_t type or larger + */ SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize) { return do_sigpending(set, sigsetsize); @@ -2233,9 +2252,9 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) err |= __put_user(from->si_trapno, &to->si_trapno); #endif #ifdef BUS_MCEERR_AO - /* + /* * Other callers might not initialize the si_lsb field, - * so check explicitely for the right codes here. + * so check explicitly for the right codes here. */ if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); @@ -2264,6 +2283,14 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from) #endif +/** + * sys_rt_sigtimedwait - synchronously wait for queued signals specified + * in @uthese + * @uthese: queued signals to wait for + * @uinfo: if non-null, the signal's siginfo is returned here + * @uts: upper bound on process time suspension + * @sigsetsize: size of sigset_t type + */ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, siginfo_t __user *, uinfo, const struct timespec __user *, uts, size_t, sigsetsize) @@ -2280,7 +2307,7 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, if (copy_from_user(&these, uthese, sizeof(these))) return -EFAULT; - + /* * Invert the set of allowed signals to get those we * want to block. @@ -2305,9 +2332,11 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, + (ts.tv_sec || ts.tv_nsec)); if (timeout) { - /* None ready -- temporarily unblock those we're + /* + * None ready -- temporarily unblock those we're * interested while we are sleeping in so that we'll - * be awakened when they arrive. */ + * be awakened when they arrive. + */ current->real_blocked = current->blocked; sigandsets(¤t->blocked, ¤t->blocked, &these); recalc_sigpending(); @@ -2339,6 +2368,11 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, return ret; } +/** + * sys_kill - send a signal to a process + * @pid: the PID of the process + * @sig: signal to be sent + */ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) { struct siginfo info; @@ -2414,7 +2448,11 @@ SYSCALL_DEFINE3(tgkill, pid_t, tgid, pid_t, pid, int, sig) return do_tkill(tgid, pid, sig); } -/* +/** + * sys_tkill - send signal to one specific task + * @pid: the PID of the task + * @sig: signal to be sent + * * Send a signal to only one task, even if it's a CLONE_THREAD task. */ SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig) @@ -2426,6 +2464,12 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig) return do_tkill(0, pid, sig); } +/** + * sys_rt_sigqueueinfo - send signal information to a signal + * @pid: the PID of the thread + * @sig: signal to be sent + * @uinfo: signal info to be sent + */ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, siginfo_t __user *, uinfo) { @@ -2553,12 +2597,11 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s error = -EINVAL; /* - * - * Note - this code used to test ss_flags incorrectly + * Note - this code used to test ss_flags incorrectly: * old code may have been written using ss_flags==0 * to mean ss_flags==SS_ONSTACK (as this was the only * way that worked) - this fix preserves that older - * mechanism + * mechanism. */ if (ss_flags != SS_DISABLE && ss_flags != SS_ONSTACK && ss_flags != 0) goto out; @@ -2592,6 +2635,10 @@ out: #ifdef __ARCH_WANT_SYS_SIGPENDING +/** + * sys_sigpending - examine pending signals + * @set: where mask of pending signal is returned + */ SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) { return do_sigpending(set, sizeof(*set)); @@ -2600,8 +2647,15 @@ SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) #endif #ifdef __ARCH_WANT_SYS_SIGPROCMASK -/* Some platforms have their own version with special arguments others - support only sys_rt_sigprocmask. */ +/** + * sys_sigprocmask - examine and change blocked signals + * @how: whether to add, remove, or set signals + * @set: signals to add or remove (if non-null) + * @oset: previous value of signal mask if non-null + * + * Some platforms have their own version with special arguments; + * others support only sys_rt_sigprocmask. + */ SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, set, old_sigset_t __user *, oset) @@ -2654,6 +2708,13 @@ out: #endif /* __ARCH_WANT_SYS_SIGPROCMASK */ #ifdef __ARCH_WANT_SYS_RT_SIGACTION +/** + * sys_rt_sigaction - alter an action taken by a process + * @sig: signal to be sent + * @act: the thread group ID of the thread + * @oact: the PID of the thread + * @sigsetsize: size of sigset_t type + */ SYSCALL_DEFINE4(rt_sigaction, int, sig, const struct sigaction __user *, act, struct sigaction __user *, oact, @@ -2740,6 +2801,12 @@ SYSCALL_DEFINE0(pause) #endif #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND +/** + * sys_rt_sigsuspend - replace the signal mask for a value with the + * @unewset value until a signal is received + * @unewset: new signal mask value + * @sigsetsize: size of sigset_t type + */ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize) { sigset_t newset; diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 5f1bb8e2008f..f6117a4c7cb8 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -652,6 +652,8 @@ int do_adjtimex(struct timex *txc) struct timespec delta; delta.tv_sec = txc->time.tv_sec; delta.tv_nsec = txc->time.tv_usec; + if (!capable(CAP_SYS_TIME)) + return -EPERM; if (!(txc->modes & ADJ_NANO)) delta.tv_nsec *= 1000; result = timekeeping_inject_offset(&delta); diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index df9234c5f9d1..c768bcdda1b7 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -434,11 +434,9 @@ config DEBUG_KMEMLEAK_EARLY_LOG_SIZE config DEBUG_KMEMLEAK_TEST tristate "Simple test for the kernel memory leak detector" - depends on DEBUG_KMEMLEAK + depends on DEBUG_KMEMLEAK && m help - Say Y or M here to build a test for the kernel memory leak - detector. This option enables a module that explicitly leaks - memory. + This option enables a module that explicitly leaks memory. If unsure, say N. diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 206e771e82d1..956a5302002a 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1051,16 +1051,17 @@ static int atalk_release(struct socket *sock) { struct sock *sk = sock->sk; - sock_hold(sk); - lock_sock(sk); if (sk) { + sock_hold(sk); + lock_sock(sk); + sock_orphan(sk); sock->sk = NULL; atalk_destroy_socket(sk); - } - release_sock(sk); - sock_put(sk); + release_sock(sk); + sock_put(sk); + } return 0; } diff --git a/net/atm/common.c b/net/atm/common.c index 1b9c52a02cd3..22b963d06a10 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -252,6 +252,7 @@ void atm_dev_release_vccs(struct atm_dev *dev) } write_unlock_irq(&vcc_sklist_lock); } +EXPORT_SYMBOL(atm_dev_release_vccs); static int adjust_tp(struct atm_trafprm *tp, unsigned char aal) { diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index b372fb8bcdcf..2216620ff296 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -186,6 +186,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) BT_DBG("%s %ld", hdev->name, opt); /* Reset device */ + set_bit(HCI_RESET, &hdev->flags); hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); } @@ -213,8 +214,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) /* Mandatory initialization */ /* Reset */ - if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) + if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { + set_bit(HCI_RESET, &hdev->flags); hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); + } /* Read Local Supported Features */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); @@ -584,6 +587,9 @@ static int hci_dev_do_close(struct hci_dev *hdev) hci_req_cancel(hdev, ENODEV); hci_req_lock(hdev); + /* Stop timer, it might be running */ + del_timer_sync(&hdev->cmd_timer); + if (!test_and_clear_bit(HCI_UP, &hdev->flags)) { hci_req_unlock(hdev); return 0; @@ -623,7 +629,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) /* Drop last sent command */ if (hdev->sent_cmd) { - del_timer_sync(&hdev->cmd_timer); kfree_skb(hdev->sent_cmd); hdev->sent_cmd = NULL; } @@ -1074,6 +1079,7 @@ static void hci_cmd_timer(unsigned long arg) BT_ERR("%s command tx timeout", hdev->name); atomic_set(&hdev->cmd_cnt, 1); + clear_bit(HCI_RESET, &hdev->flags); tasklet_schedule(&hdev->cmd_task); } diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3fbfa50c2bff..cebe7588469f 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -183,6 +183,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s status 0x%x", hdev->name, status); + clear_bit(HCI_RESET, &hdev->flags); + hci_req_complete(hdev, HCI_OP_RESET, status); } @@ -1847,7 +1849,7 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) if (ev->opcode != HCI_OP_NOP) del_timer(&hdev->cmd_timer); - if (ev->ncmd) { + if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) { atomic_set(&hdev->cmd_cnt, 1); if (!skb_queue_empty(&hdev->cmd_q)) tasklet_schedule(&hdev->cmd_task); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c9f9cecca527..ca27f3a41536 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1116,7 +1116,9 @@ int l2cap_ertm_send(struct sock *sk) bt_cb(skb)->tx_seq = pi->next_tx_seq; pi->next_tx_seq = (pi->next_tx_seq + 1) % 64; - pi->unacked_frames++; + if (bt_cb(skb)->retries == 1) + pi->unacked_frames++; + pi->frames_sent++; if (skb_queue_is_last(TX_QUEUE(sk), skb)) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index fc85e7ae33c7..f77308e63e58 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -923,8 +923,9 @@ void __l2cap_sock_close(struct sock *sk, int reason) rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); - } else - l2cap_chan_del(sk, reason); + } + + l2cap_chan_del(sk, reason); break; case BT_CONNECT: diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 0054c74e27b7..4476d8e3c0f2 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -1230,6 +1230,8 @@ static int user_confirm_reply(struct sock *sk, u16 index, unsigned char *data, if (!hdev) return cmd_status(sk, index, mgmt_op, ENODEV); + hci_dev_lock_bh(hdev); + if (!test_bit(HCI_UP, &hdev->flags)) { err = cmd_status(sk, index, mgmt_op, ENETDOWN); goto failed; diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index f61eb2eff3fd..59660c909a7c 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -1475,7 +1475,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, ip6h->payload_len == 0) return 0; - len = ntohs(ip6h->payload_len); + len = ntohs(ip6h->payload_len) + sizeof(*ip6h); if (skb->len < len) return -EINVAL; diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 5593f5aec942..9b61d09de9b9 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -213,7 +213,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) /* user has chosen a value so keep it */ if (br->flags & BR_SET_MAC_ADDR) - return; + return false; list_for_each_entry(p, &br->port_list, list) { if (addr == br_mac_zero || diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig index ad424049b0cf..be683f2d401f 100644 --- a/net/ceph/Kconfig +++ b/net/ceph/Kconfig @@ -4,6 +4,7 @@ config CEPH_LIB select LIBCRC32C select CRYPTO_AES select CRYPTO + select KEYS default n help Choose Y or M here to include cephlib, which provides the diff --git a/net/ceph/auth.c b/net/ceph/auth.c index 549c1f43e1d5..b4bf4ac090f1 100644 --- a/net/ceph/auth.c +++ b/net/ceph/auth.c @@ -35,12 +35,12 @@ static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol) /* * setup, teardown. */ -struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) +struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key) { struct ceph_auth_client *ac; int ret; - dout("auth_init name '%s' secret '%s'\n", name, secret); + dout("auth_init name '%s'\n", name); ret = -ENOMEM; ac = kzalloc(sizeof(*ac), GFP_NOFS); @@ -52,8 +52,8 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) ac->name = name; else ac->name = CEPH_AUTH_NAME_DEFAULT; - dout("auth_init name %s secret %s\n", ac->name, secret); - ac->secret = secret; + dout("auth_init name %s\n", ac->name); + ac->key = key; return ac; out: diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 7fd5dfcf6e18..1587dc6010c6 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c @@ -662,14 +662,16 @@ int ceph_x_init(struct ceph_auth_client *ac) goto out; ret = -EINVAL; - if (!ac->secret) { + if (!ac->key) { pr_err("no secret set (for auth_x protocol)\n"); goto out_nomem; } - ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret); - if (ret) + ret = ceph_crypto_key_clone(&xi->secret, ac->key); + if (ret < 0) { + pr_err("cannot clone key: %d\n", ret); goto out_nomem; + } xi->starting = true; xi->ticket_handlers = RB_ROOT; diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 95f96ab94bba..132963abc266 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -5,6 +5,8 @@ #include <linux/fs.h> #include <linux/inet.h> #include <linux/in6.h> +#include <linux/key.h> +#include <keys/ceph-type.h> #include <linux/module.h> #include <linux/mount.h> #include <linux/parser.h> @@ -20,6 +22,7 @@ #include <linux/ceph/decode.h> #include <linux/ceph/mon_client.h> #include <linux/ceph/auth.h> +#include "crypto.h" @@ -117,9 +120,29 @@ int ceph_compare_options(struct ceph_options *new_opt, if (ret) return ret; - ret = strcmp_null(opt1->secret, opt2->secret); - if (ret) - return ret; + if (opt1->key && !opt2->key) + return -1; + if (!opt1->key && opt2->key) + return 1; + if (opt1->key && opt2->key) { + if (opt1->key->type != opt2->key->type) + return -1; + if (opt1->key->created.tv_sec != opt2->key->created.tv_sec) + return -1; + if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec) + return -1; + if (opt1->key->len != opt2->key->len) + return -1; + if (opt1->key->key && !opt2->key->key) + return -1; + if (!opt1->key->key && opt2->key->key) + return 1; + if (opt1->key->key && opt2->key->key) { + ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len); + if (ret) + return ret; + } + } /* any matching mon ip implies a match */ for (i = 0; i < opt1->num_mon; i++) { @@ -176,6 +199,7 @@ enum { Opt_fsid, Opt_name, Opt_secret, + Opt_key, Opt_ip, Opt_last_string, /* string args above */ @@ -192,6 +216,7 @@ static match_table_t opt_tokens = { {Opt_fsid, "fsid=%s"}, {Opt_name, "name=%s"}, {Opt_secret, "secret=%s"}, + {Opt_key, "key=%s"}, {Opt_ip, "ip=%s"}, /* string args above */ {Opt_noshare, "noshare"}, @@ -203,11 +228,56 @@ void ceph_destroy_options(struct ceph_options *opt) { dout("destroy_options %p\n", opt); kfree(opt->name); - kfree(opt->secret); + if (opt->key) { + ceph_crypto_key_destroy(opt->key); + kfree(opt->key); + } kfree(opt); } EXPORT_SYMBOL(ceph_destroy_options); +/* get secret from key store */ +static int get_secret(struct ceph_crypto_key *dst, const char *name) { + struct key *ukey; + int key_err; + int err = 0; + struct ceph_crypto_key *ckey; + + ukey = request_key(&key_type_ceph, name, NULL); + if (!ukey || IS_ERR(ukey)) { + /* request_key errors don't map nicely to mount(2) + errors; don't even try, but still printk */ + key_err = PTR_ERR(ukey); + switch (key_err) { + case -ENOKEY: + pr_warning("ceph: Mount failed due to key not found: %s\n", name); + break; + case -EKEYEXPIRED: + pr_warning("ceph: Mount failed due to expired key: %s\n", name); + break; + case -EKEYREVOKED: + pr_warning("ceph: Mount failed due to revoked key: %s\n", name); + break; + default: + pr_warning("ceph: Mount failed due to unknown key error" + " %d: %s\n", key_err, name); + } + err = -EPERM; + goto out; + } + + ckey = ukey->payload.data; + err = ceph_crypto_key_clone(dst, ckey); + if (err) + goto out_key; + /* pass through, err is 0 */ + +out_key: + key_put(ukey); +out: + return err; +} + int ceph_parse_options(struct ceph_options **popt, char *options, const char *dev_name, const char *dev_name_end, int (*parse_extra_token)(char *c, void *private), @@ -295,9 +365,24 @@ int ceph_parse_options(struct ceph_options **popt, char *options, GFP_KERNEL); break; case Opt_secret: - opt->secret = kstrndup(argstr[0].from, - argstr[0].to-argstr[0].from, - GFP_KERNEL); + opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); + if (!opt->key) { + err = -ENOMEM; + goto out; + } + err = ceph_crypto_key_unarmor(opt->key, argstr[0].from); + if (err < 0) + goto out; + break; + case Opt_key: + opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); + if (!opt->key) { + err = -ENOMEM; + goto out; + } + err = get_secret(opt->key, argstr[0].from); + if (err < 0) + goto out; break; /* misc */ @@ -394,8 +479,8 @@ void ceph_destroy_client(struct ceph_client *client) ceph_osdc_stop(&client->osdc); /* - * make sure mds and osd connections close out before destroying - * the auth module, which is needed to free those connections' + * make sure osd connections close out before destroying the + * auth module, which is needed to free those connections' * ceph_authorizers. */ ceph_msgr_flush(); @@ -496,10 +581,14 @@ static int __init init_ceph_lib(void) if (ret < 0) goto out; - ret = ceph_msgr_init(); + ret = ceph_crypto_init(); if (ret < 0) goto out_debugfs; + ret = ceph_msgr_init(); + if (ret < 0) + goto out_crypto; + pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n", CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL, CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT, @@ -507,6 +596,8 @@ static int __init init_ceph_lib(void) return 0; +out_crypto: + ceph_crypto_shutdown(); out_debugfs: ceph_debugfs_cleanup(); out: @@ -517,6 +608,7 @@ static void __exit exit_ceph_lib(void) { dout("exit_ceph_lib\n"); ceph_msgr_exit(); + ceph_crypto_shutdown(); ceph_debugfs_cleanup(); } diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 7b505b0c983f..5a8009c9e0cd 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -5,10 +5,23 @@ #include <linux/scatterlist.h> #include <linux/slab.h> #include <crypto/hash.h> +#include <linux/key-type.h> +#include <keys/ceph-type.h> #include <linux/ceph/decode.h> #include "crypto.h" +int ceph_crypto_key_clone(struct ceph_crypto_key *dst, + const struct ceph_crypto_key *src) +{ + memcpy(dst, src, sizeof(struct ceph_crypto_key)); + dst->key = kmalloc(src->len, GFP_NOFS); + if (!dst->key) + return -ENOMEM; + memcpy(dst->key, src->key, src->len); + return 0; +} + int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end) { if (*p + sizeof(u16) + sizeof(key->created) + @@ -410,3 +423,63 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, return -EINVAL; } } + +int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) +{ + struct ceph_crypto_key *ckey; + int ret; + void *p; + + ret = -EINVAL; + if (datalen <= 0 || datalen > 32767 || !data) + goto err; + + ret = key_payload_reserve(key, datalen); + if (ret < 0) + goto err; + + ret = -ENOMEM; + ckey = kmalloc(sizeof(*ckey), GFP_KERNEL); + if (!ckey) + goto err; + + /* TODO ceph_crypto_key_decode should really take const input */ + p = (void*)data; + ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen); + if (ret < 0) + goto err_ckey; + + key->payload.data = ckey; + return 0; + +err_ckey: + kfree(ckey); +err: + return ret; +} + +int ceph_key_match(const struct key *key, const void *description) +{ + return strcmp(key->description, description) == 0; +} + +void ceph_key_destroy(struct key *key) { + struct ceph_crypto_key *ckey = key->payload.data; + + ceph_crypto_key_destroy(ckey); +} + +struct key_type key_type_ceph = { + .name = "ceph", + .instantiate = ceph_key_instantiate, + .match = ceph_key_match, + .destroy = ceph_key_destroy, +}; + +int ceph_crypto_init(void) { + return register_key_type(&key_type_ceph); +} + +void ceph_crypto_shutdown(void) { + unregister_key_type(&key_type_ceph); +} diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h index f9eccace592b..1919d1550d75 100644 --- a/net/ceph/crypto.h +++ b/net/ceph/crypto.h @@ -19,6 +19,8 @@ static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key) kfree(key->key); } +extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst, + const struct ceph_crypto_key *src); extern int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end); extern int ceph_crypto_key_decode(struct ceph_crypto_key *key, @@ -40,6 +42,8 @@ extern int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, const void *src1, size_t src1_len, const void *src2, size_t src2_len); +extern int ceph_crypto_init(void); +extern void ceph_crypto_shutdown(void); /* armor.c */ extern int ceph_armor(char *dst, const char *src, const char *end); diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 8a079399174a..cbe31fa45508 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -759,7 +759,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl) /* authentication */ monc->auth = ceph_auth_init(cl->options->name, - cl->options->secret); + cl->options->key); if (IS_ERR(monc->auth)) return PTR_ERR(monc->auth); monc->auth->want_keys = diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 02212ed50852..3b91d651fe08 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -837,8 +837,7 @@ static void __unregister_request(struct ceph_osd_client *osdc, dout("moving osd to %p lru\n", req->r_osd); __move_osd_to_lru(osdc, req->r_osd); } - if (list_empty(&req->r_osd_item) && - list_empty(&req->r_linger_item)) + if (list_empty(&req->r_linger_item)) req->r_osd = NULL; } @@ -883,7 +882,8 @@ static void __unregister_linger_request(struct ceph_osd_client *osdc, dout("moving osd to %p lru\n", req->r_osd); __move_osd_to_lru(osdc, req->r_osd); } - req->r_osd = NULL; + if (list_empty(&req->r_osd_item)) + req->r_osd = NULL; } } @@ -1602,11 +1602,11 @@ void handle_watch_notify(struct ceph_osd_client *osdc, struct ceph_msg *msg) cookie, ver, event); if (event) { event_work = kmalloc(sizeof(*event_work), GFP_NOIO); - INIT_WORK(&event_work->work, do_event_work); if (!event_work) { dout("ERROR: could not allocate event_work\n"); goto done_err; } + INIT_WORK(&event_work->work, do_event_work); event_work->event = event; event_work->ver = ver; event_work->notify_id = notify_id; @@ -1672,7 +1672,7 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, if (req->r_sent == 0) { rc = __map_request(osdc, req); if (rc < 0) - return rc; + goto out_unlock; if (req->r_osd == NULL) { dout("send_request %p no up osds in pg\n", req); ceph_monc_request_next_osdmap(&osdc->client->monc); @@ -1689,6 +1689,8 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc, } } } + +out_unlock: mutex_unlock(&osdc->request_mutex); up_read(&osdc->map_sem); return rc; diff --git a/net/core/dev.c b/net/core/dev.c index 563ddc28139d..3da9fb06d47a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1454,6 +1454,27 @@ static inline void net_timestamp_check(struct sk_buff *skb) __net_timestamp(skb); } +static inline bool is_skb_forwardable(struct net_device *dev, + struct sk_buff *skb) +{ + unsigned int len; + + if (!(dev->flags & IFF_UP)) + return false; + + len = dev->mtu + dev->hard_header_len + VLAN_HLEN; + if (skb->len <= len) + return true; + + /* if TSO is enabled, we don't care about the length as the packet + * could be forwarded without being segmented before + */ + if (skb_is_gso(skb)) + return true; + + return false; +} + /** * dev_forward_skb - loopback an skb to another netif * @@ -1477,8 +1498,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) skb_orphan(skb); nf_reset(skb); - if (unlikely(!(dev->flags & IFF_UP) || - (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) { + if (unlikely(!is_skb_forwardable(dev, skb))) { atomic_long_inc(&dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 090d273d7865..1b74d3b64371 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -215,6 +215,9 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir) case ARPHRD_INFINIBAND: ip_ib_mc_map(addr, dev->broadcast, haddr); return 0; + case ARPHRD_IPGRE: + ip_ipgre_mc_map(addr, dev->broadcast, haddr); + return 0; default: if (dir) { memcpy(haddr, dev->broadcast, dev->addr_len); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index f116ce8f1b46..451088330bbb 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -1068,6 +1068,7 @@ static void ip_fib_net_exit(struct net *net) fib4_rules_exit(net); #endif + rtnl_lock(); for (i = 0; i < FIB_TABLE_HASHSZ; i++) { struct fib_table *tb; struct hlist_head *head; @@ -1080,6 +1081,7 @@ static void ip_fib_net_exit(struct net *net) fib_free_table(tb); } } + rtnl_unlock(); kfree(net->ipv4.fib_table_hash); } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index dfa5beb0c1c8..8b0d0167e44a 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1003,7 +1003,8 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, int nlen; u8 flags; - BUG_ON(len > skb->len); + if (WARN_ON(len > skb->len)) + return -EINVAL; nsize = skb_headlen(skb) - len; if (nsize < 0) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 0e49c9db3c98..92f952d093db 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -341,6 +341,8 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d case ARPHRD_INFINIBAND: ipv6_ib_mc_map(addr, dev->broadcast, buf); return 0; + case ARPHRD_IPGRE: + return ipv6_ipgre_mc_map(addr, dev->broadcast, buf); default: if (dir) { memcpy(buf, dev->broadcast, dev->addr_len); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 2b0c186862c8..56fa12538d45 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -503,6 +503,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (IS_ERR(dst)) { err = PTR_ERR(dst); + dst = NULL; goto done; } skb = tcp_make_synack(sk, dst, req, rvp); diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 8c02469b7176..af3c56482c80 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -342,7 +342,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, if (IS_ERR(key->u.ccmp.tfm)) { err = PTR_ERR(key->u.ccmp.tfm); kfree(key); - key = ERR_PTR(err); + return ERR_PTR(err); } break; case WLAN_CIPHER_SUITE_AES_CMAC: @@ -360,7 +360,7 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, if (IS_ERR(key->u.aes_cmac.tfm)) { err = PTR_ERR(key->u.aes_cmac.tfm); kfree(key); - key = ERR_PTR(err); + return ERR_PTR(err); } break; } @@ -400,11 +400,12 @@ int ieee80211_key_link(struct ieee80211_key *key, { struct ieee80211_key *old_key; int idx, ret; - bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; + bool pairwise; BUG_ON(!sdata); BUG_ON(!key); + pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; idx = key->conf.keyidx; key->local = sdata->local; key->sdata = sdata; diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 8212a8bebf06..dbdebeda097f 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -659,18 +659,14 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; struct ieee80211_local *local = hw_to_local(mp->hw); u16 sta_cap = sta->ht_cap.cap; + int n_supported = 0; int ack_dur; int stbc; int i; /* fall back to the old minstrel for legacy stations */ - if (!sta->ht_cap.ht_supported) { - msp->is_ht = false; - memset(&msp->legacy, 0, sizeof(msp->legacy)); - msp->legacy.r = msp->ratelist; - msp->legacy.sample_table = msp->sample_table; - return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy); - } + if (!sta->ht_cap.ht_supported) + goto use_legacy; BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS); @@ -725,7 +721,22 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, mi->groups[i].supported = mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; + + if (mi->groups[i].supported) + n_supported++; } + + if (!n_supported) + goto use_legacy; + + return; + +use_legacy: + msp->is_ht = false; + memset(&msp->legacy, 0, sizeof(msp->legacy)); + msp->legacy.r = msp->ratelist; + msp->legacy.sample_table = msp->sample_table; + return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy); } static void diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5c1930ba8ebe..aa5cc37b4921 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -612,7 +612,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, skipped++; continue; } - if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + + if (skipped && + !time_after(jiffies, tid_agg_rx->reorder_time[j] + HT_RX_REORDER_BUF_TIMEOUT)) goto set_release_timer; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 152976ec0b74..d5bf91d04f63 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1205,7 +1205,7 @@ SCTP_STATIC __init int sctp_init(void) if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0) continue; sctp_assoc_hashtable = (struct sctp_hashbucket *) - __get_free_pages(GFP_ATOMIC, order); + __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order); } while (!sctp_assoc_hashtable && --order > 0); if (!sctp_assoc_hashtable) { pr_err("Failed association hash alloc\n"); @@ -1238,7 +1238,7 @@ SCTP_STATIC __init int sctp_init(void) if ((sctp_port_hashsize > (64 * 1024)) && order > 0) continue; sctp_port_hashtable = (struct sctp_bind_hashbucket *) - __get_free_pages(GFP_ATOMIC, order); + __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order); } while (!sctp_port_hashtable && --order > 0); if (!sctp_port_hashtable) { pr_err("Failed bind hash alloc\n"); diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index de98665db524..b3434cc7d0cf 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -3106,10 +3106,10 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, /* create an ASCONF_ACK chunk. * Based on the definitions of parameters, we know that the size of - * ASCONF_ACK parameters are less than or equal to the twice of ASCONF + * ASCONF_ACK parameters are less than or equal to the fourfold of ASCONF * parameters. */ - asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 2); + asconf_ack = sctp_make_asconf_ack(asoc, serial, chunk_len * 4); if (!asconf_ack) goto done; diff --git a/net/wireless/scan.c b/net/wireless/scan.c index ea427f418f64..fbf6f33ae4d0 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -124,6 +124,15 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev, } /* must hold dev->bss_lock! */ +static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev, + struct cfg80211_internal_bss *bss) +{ + list_del_init(&bss->list); + rb_erase(&bss->rbn, &dev->bss_tree); + kref_put(&bss->ref, bss_release); +} + +/* must hold dev->bss_lock! */ void cfg80211_bss_expire(struct cfg80211_registered_device *dev) { struct cfg80211_internal_bss *bss, *tmp; @@ -134,9 +143,7 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev) continue; if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE)) continue; - list_del(&bss->list); - rb_erase(&bss->rbn, &dev->bss_tree); - kref_put(&bss->ref, bss_release); + __cfg80211_unlink_bss(dev, bss); expired = true; } @@ -585,16 +592,23 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, struct cfg80211_internal_bss *res; size_t ielen = len - offsetof(struct ieee80211_mgmt, u.probe_resp.variable); - size_t privsz = wiphy->bss_priv_size; + size_t privsz; + + if (WARN_ON(!mgmt)) + return NULL; + + if (WARN_ON(!wiphy)) + return NULL; if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && (signal < 0 || signal > 100))) return NULL; - if (WARN_ON(!mgmt || !wiphy || - len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable))) + if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable))) return NULL; + privsz = wiphy->bss_priv_size; + res = kzalloc(sizeof(*res) + privsz + ielen, gfp); if (!res) return NULL; @@ -662,11 +676,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) spin_lock_bh(&dev->bss_lock); if (!list_empty(&bss->list)) { - list_del_init(&bss->list); + __cfg80211_unlink_bss(dev, bss); dev->bss_generation++; - rb_erase(&bss->rbn, &dev->bss_tree); - - kref_put(&bss->ref, bss_release); } spin_unlock_bh(&dev->bss_lock); } diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index a82e3756a72d..64449cb8f873 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -375,6 +375,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, } if (runtime->no_period_wakeup) { + snd_pcm_sframes_t xrun_threshold; /* * Without regular period interrupts, we have to check * the elapsed time to detect xruns. @@ -383,7 +384,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, if (jdelta < runtime->hw_ptr_buffer_jiffies / 2) goto no_delta_check; hdelta = jdelta - delta * HZ / runtime->rate; - while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) { + xrun_threshold = runtime->hw_ptr_buffer_jiffies / 2 + 1; + while (hdelta > xrun_threshold) { delta += runtime->buffer_size; hw_base += runtime->buffer_size; if (hw_base >= runtime->boundary) diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c index 0fce9218abb1..5466de8527bd 100644 --- a/sound/firewire/speakers.c +++ b/sound/firewire/speakers.c @@ -778,10 +778,9 @@ static int __devexit fwspk_remove(struct device *dev) { struct fwspk *fwspk = dev_get_drvdata(dev); - snd_card_disconnect(fwspk->card); - mutex_lock(&fwspk->mutex); amdtp_out_stream_pcm_abort(&fwspk->stream); + snd_card_disconnect(fwspk->card); fwspk_stop_stream(fwspk); mutex_unlock(&fwspk->mutex); diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 537cfba829a5..863eafea691f 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -229,6 +229,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force)."); #define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */ #define ES_1371_CODEC_RDY (1<<31) /* codec ready */ #define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */ +#define EV_1938_CODEC_MAGIC (1<<26) #define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */ #define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0)) #define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD) @@ -603,12 +604,18 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531, #ifdef CHIP1371 +static inline bool is_ev1938(struct ensoniq *ensoniq) +{ + return ensoniq->pci->device == 0x8938; +} + static void snd_es1371_codec_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { struct ensoniq *ensoniq = ac97->private_data; - unsigned int t, x; + unsigned int t, x, flag; + flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0; mutex_lock(&ensoniq->src_mutex); for (t = 0; t < POLL_COUNT; t++) { if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { @@ -630,7 +637,8 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, 0x00010000) break; } - outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC)); + outl(ES_1371_CODEC_WRITE(reg, val) | flag, + ES_REG(ensoniq, 1371_CODEC)); /* restore SRC reg */ snd_es1371_wait_src_ready(ensoniq); outl(x, ES_REG(ensoniq, 1371_SMPRATE)); @@ -647,8 +655,9 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, unsigned short reg) { struct ensoniq *ensoniq = ac97->private_data; - unsigned int t, x, fail = 0; + unsigned int t, x, flag, fail = 0; + flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0; __again: mutex_lock(&ensoniq->src_mutex); for (t = 0; t < POLL_COUNT; t++) { @@ -671,7 +680,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, 0x00010000) break; } - outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC)); + outl(ES_1371_CODEC_READS(reg) | flag, + ES_REG(ensoniq, 1371_CODEC)); /* restore SRC reg */ snd_es1371_wait_src_ready(ensoniq); outl(x, ES_REG(ensoniq, 1371_SMPRATE)); @@ -683,6 +693,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, /* now wait for the stinkin' data (RDY) */ for (t = 0; t < POLL_COUNT; t++) { if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { + if (is_ev1938(ensoniq)) { + for (t = 0; t < 100; t++) + inl(ES_REG(ensoniq, CONTROL)); + x = inl(ES_REG(ensoniq, 1371_CODEC)); + } mutex_unlock(&ensoniq->src_mutex); return ES_1371_CODEC_READ(x); } diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index d08cf31596f3..69e33869a53e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3034,6 +3034,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), + SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ {} diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0ef0035fe99f..12c6f4508c54 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9863,7 +9863,6 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), @@ -10700,6 +10699,7 @@ enum { PINFIX_LENOVO_Y530, PINFIX_PB_M5210, PINFIX_ACER_ASPIRE_7736, + PINFIX_GIGABYTE_880GM, }; static const struct alc_fixup alc882_fixups[] = { @@ -10731,6 +10731,13 @@ static const struct alc_fixup alc882_fixups[] = { .type = ALC_FIXUP_SKU, .v.sku = ALC_FIXUP_SKU_IGNORE, }, + [PINFIX_GIGABYTE_880GM] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x1114410 }, /* set as speaker */ + { } + } + }, }; static struct snd_pci_quirk alc882_fixup_tbl[] = { @@ -10738,6 +10745,7 @@ static struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM), {} }; @@ -18774,8 +18782,6 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", - ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), @@ -19449,6 +19455,7 @@ enum { ALC662_FIXUP_IDEAPAD, ALC272_FIXUP_MARIO, ALC662_FIXUP_CZC_P10T, + ALC662_FIXUP_GIGABYTE, }; static const struct alc_fixup alc662_fixups[] = { @@ -19477,12 +19484,20 @@ static const struct alc_fixup alc662_fixups[] = { {} } }, + [ALC662_FIXUP_GIGABYTE] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x1114410 }, /* set as speaker */ + { } + } + }, }; static struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 2a30eae1881c..a54d2a5b28f6 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -26,7 +26,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/platform_device.h> +#include <linux/delay.h> #include <linux/slab.h> + #include <asm/intel_scu_ipc.h> #include <sound/pcm.h> #include <sound/pcm_params.h> diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 00b6d87e7bdb..eb1a0b4e09b6 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -324,6 +324,10 @@ static void dac33_init_chip(struct snd_soc_codec *codec) dac33_write(codec, DAC33_OUT_AMP_CTRL, dac33_read_reg_cache(codec, DAC33_OUT_AMP_CTRL)); + dac33_write(codec, DAC33_LDAC_PWR_CTRL, + dac33_read_reg_cache(codec, DAC33_LDAC_PWR_CTRL)); + dac33_write(codec, DAC33_RDAC_PWR_CTRL, + dac33_read_reg_cache(codec, DAC33_RDAC_PWR_CTRL)); } static inline int dac33_read_id(struct snd_soc_codec *codec) @@ -670,6 +674,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) { struct snd_soc_codec *codec = dac33->codec; unsigned int delay; + unsigned long flags; switch (dac33->fifo_mode) { case DAC33_FIFO_MODE1: @@ -677,10 +682,10 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) DAC33_THRREG(dac33->nsample)); /* Take the timestamps */ - spin_lock_irq(&dac33->lock); + spin_lock_irqsave(&dac33->lock, flags); dac33->t_stamp2 = ktime_to_us(ktime_get()); dac33->t_stamp1 = dac33->t_stamp2; - spin_unlock_irq(&dac33->lock); + spin_unlock_irqrestore(&dac33->lock, flags); dac33_write16(codec, DAC33_PREFILL_MSB, DAC33_THRREG(dac33->alarm_threshold)); @@ -692,11 +697,11 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) break; case DAC33_FIFO_MODE7: /* Take the timestamp */ - spin_lock_irq(&dac33->lock); + spin_lock_irqsave(&dac33->lock, flags); dac33->t_stamp1 = ktime_to_us(ktime_get()); /* Move back the timestamp with drain time */ dac33->t_stamp1 -= dac33->mode7_us_to_lthr; - spin_unlock_irq(&dac33->lock); + spin_unlock_irqrestore(&dac33->lock, flags); dac33_write16(codec, DAC33_PREFILL_MSB, DAC33_THRREG(DAC33_MODE7_MARGIN)); @@ -714,13 +719,14 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33) { struct snd_soc_codec *codec = dac33->codec; + unsigned long flags; switch (dac33->fifo_mode) { case DAC33_FIFO_MODE1: /* Take the timestamp */ - spin_lock_irq(&dac33->lock); + spin_lock_irqsave(&dac33->lock, flags); dac33->t_stamp2 = ktime_to_us(ktime_get()); - spin_unlock_irq(&dac33->lock); + spin_unlock_irqrestore(&dac33->lock, flags); dac33_write16(codec, DAC33_NSAMPLE_MSB, DAC33_THRREG(dac33->nsample)); @@ -773,10 +779,11 @@ static irqreturn_t dac33_interrupt_handler(int irq, void *dev) { struct snd_soc_codec *codec = dev; struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); + unsigned long flags; - spin_lock(&dac33->lock); + spin_lock_irqsave(&dac33->lock, flags); dac33->t_stamp1 = ktime_to_us(ktime_get()); - spin_unlock(&dac33->lock); + spin_unlock_irqrestore(&dac33->lock, flags); /* Do not schedule the workqueue in Mode7 */ if (dac33->fifo_mode != DAC33_FIFO_MODE7) @@ -1173,15 +1180,16 @@ static snd_pcm_sframes_t dac33_dai_delay( unsigned int time_delta, uthr; int samples_out, samples_in, samples; snd_pcm_sframes_t delay = 0; + unsigned long flags; switch (dac33->fifo_mode) { case DAC33_FIFO_BYPASS: break; case DAC33_FIFO_MODE1: - spin_lock(&dac33->lock); + spin_lock_irqsave(&dac33->lock, flags); t0 = dac33->t_stamp1; t1 = dac33->t_stamp2; - spin_unlock(&dac33->lock); + spin_unlock_irqrestore(&dac33->lock, flags); t_now = ktime_to_us(ktime_get()); /* We have not started to fill the FIFO yet, delay is 0 */ @@ -1246,10 +1254,10 @@ static snd_pcm_sframes_t dac33_dai_delay( } break; case DAC33_FIFO_MODE7: - spin_lock(&dac33->lock); + spin_lock_irqsave(&dac33->lock, flags); t0 = dac33->t_stamp1; uthr = dac33->uthr; - spin_unlock(&dac33->lock); + spin_unlock_irqrestore(&dac33->lock, flags); t_now = ktime_to_us(ktime_get()); /* We have not started to fill the FIFO yet, delay is 0 */ diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 482fcdb59bfa..255901c4460d 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1629,8 +1629,10 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->naudint = naudint; priv->workqueue = create_singlethread_workqueue("twl6040-codec"); - if (!priv->workqueue) + if (!priv->workqueue) { + ret = -ENOMEM; goto work_err; + } INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work); diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 671ef8dd524c..aab7765f401a 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -110,12 +110,12 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, slave_config.direction = DMA_TO_DEVICE; slave_config.dst_addr = dma_params->dma_addr; slave_config.dst_addr_width = buswidth; - slave_config.dst_maxburst = dma_params->burstsize; + slave_config.dst_maxburst = dma_params->burstsize * buswidth; } else { slave_config.direction = DMA_FROM_DEVICE; slave_config.src_addr = dma_params->dma_addr; slave_config.src_addr_width = buswidth; - slave_config.src_maxburst = dma_params->burstsize; + slave_config.src_maxburst = dma_params->burstsize * buswidth; } ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); @@ -303,6 +303,11 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = { static int __devinit imx_soc_platform_probe(struct platform_device *pdev) { + struct imx_ssi *ssi = platform_get_drvdata(pdev); + + ssi->dma_params_tx.burstsize = 6; + ssi->dma_params_rx.burstsize = 4; + return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); } diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h index a4406a134892..dc8a87530e3e 100644 --- a/sound/soc/imx/imx-ssi.h +++ b/sound/soc/imx/imx-ssi.h @@ -234,7 +234,4 @@ void imx_pcm_free(struct snd_pcm *pcm); */ #define IMX_SSI_DMABUF_SIZE (64 * 1024) -#define DMA_RXFIFO_BURST 0x4 -#define DMA_TXFIFO_BURST 0x6 - #endif /* _IMX_SSI_H */ diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 784cff5f67e8..9027da466cae 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -310,7 +310,7 @@ static struct snd_soc_dai_link corgi_dai = { .cpu_dai_name = "pxa2xx-i2s", .codec_dai_name = "wm8731-hifi", .platform_name = "pxa-pcm-audio", - .codec_name = "wm8731-codec-0.001b", + .codec_name = "wm8731-codec.0-001b", .init = corgi_wm8731_init, .ops = &corgi_ops, }; diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index fcab80b36a37..fc017c0a7b5d 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -331,7 +331,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, goto err; if (gpios[i].wake) { - ret = set_irq_wake(gpio_to_irq(gpios[i].gpio), 1); + ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1); if (ret != 0) printk(KERN_ERR "Failed to mark GPIO %d as wake source: %d\n", diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 158c30e8210c..207dee5c5b16 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -165,8 +165,12 @@ grep-libs = $(filter -l%,$(1)) strip-libs = $(filter-out -l%,$(1)) $(OUTPUT)python/perf.so: $(PYRF_OBJS) - $(QUIET_GEN)python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ - --build-temp='$(OUTPUT)python/temp' + $(QUIET_GEN)( \ + export CFLAGS="$(BASIC_CFLAGS)"; \ + python util/setup.py --quiet build_ext --build-lib='$(OUTPUT)python' \ + --build-temp='$(OUTPUT)python/temp' \ + ) + # # No Perl scripts right now: # diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 6febcc168a8c..17d1dcb3c667 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -41,7 +41,7 @@ static u64 user_interval = ULLONG_MAX; static u64 default_interval = 0; static unsigned int page_size; -static unsigned int mmap_pages = 128; +static unsigned int mmap_pages = UINT_MAX; static unsigned int user_freq = UINT_MAX; static int freq = 1000; static int output; @@ -275,11 +275,10 @@ try_again: !no_inherit) < 0) { int err = errno; - if (err == EPERM || err == EACCES) - die("Permission error - are you root?\n" - "\t Consider tweaking" - " /proc/sys/kernel/perf_event_paranoid.\n"); - else if (err == ENODEV && cpu_list) { + if (err == EPERM || err == EACCES) { + ui__warning_paranoid(); + exit(EXIT_FAILURE); + } else if (err == ENODEV && cpu_list) { die("No such device - did you specify" " an out-of-range profile CPU?\n"); } else if (err == EINVAL && sample_id_all_avail) { @@ -302,11 +301,19 @@ try_again: && attr->config == PERF_COUNT_HW_CPU_CYCLES) { if (verbose) - warning(" ... trying to fall back to cpu-clock-ticks\n"); + ui__warning("The cycles event is not supported, " + "trying to fall back to cpu-clock-ticks\n"); attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; goto try_again; } + + if (err == ENOENT) { + ui__warning("The %s event is not supported.\n", + event_name(pos)); + exit(EXIT_FAILURE); + } + printf("\n"); error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", err, strerror(err)); @@ -506,6 +513,10 @@ static int __cmd_record(int argc, const char **argv) if (have_tracepoints(&evsel_list->entries)) perf_header__set_feat(&session->header, HEADER_TRACE_INFO); + /* 512 kiB: default amount of unprivileged mlocked memory */ + if (mmap_pages == UINT_MAX) + mmap_pages = (512 * 1024) / page_size; + if (forks) { child_pid = fork(); if (child_pid < 0) { diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 676b4fb0070f..fc1273e976c5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -850,10 +850,10 @@ try_again: top.evlist->threads, group, inherit) < 0) { int err = errno; - if (err == EPERM || err == EACCES) - die("Permission error - are you root?\n" - "\t Consider tweaking" - " /proc/sys/kernel/perf_event_paranoid.\n"); + if (err == EPERM || err == EACCES) { + ui__warning_paranoid(); + goto out_err; + } /* * If it's cycles then fall back to hrtimer * based cpu-clock-tick sw counter, which @@ -861,25 +861,41 @@ try_again: */ if (attr->type == PERF_TYPE_HARDWARE && attr->config == PERF_COUNT_HW_CPU_CYCLES) { - if (verbose) - warning(" ... trying to fall back to cpu-clock-ticks\n"); + ui__warning("Cycles event not supported,\n" + "trying to fall back to cpu-clock-ticks\n"); attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; goto try_again; } - printf("\n"); - error("sys_perf_event_open() syscall returned with %d " - "(%s). /bin/dmesg may provide additional information.\n", - err, strerror(err)); - die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); - exit(-1); + + if (err == ENOENT) { + ui__warning("The %s event is not supported.\n", + event_name(counter)); + goto out_err; + } + + ui__warning("The sys_perf_event_open() syscall " + "returned with %d (%s). /bin/dmesg " + "may provide additional information.\n" + "No CONFIG_PERF_EVENTS=y kernel support " + "configured?\n", err, strerror(err)); + goto out_err; } } - if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) - die("failed to mmap with %d (%s)\n", errno, strerror(errno)); + if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) { + ui__warning("Failed to mmap with %d (%s)\n", + errno, strerror(errno)); + goto out_err; + } + + return; + +out_err: + exit_browser(0); + exit(0); } static int __cmd_top(void) diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index d4536a9e0d8c..155749d74350 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -57,6 +57,16 @@ void ui__warning(const char *format, ...) } #endif +void ui__warning_paranoid(void) +{ + ui__warning("Permission error - are you root?\n" + "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" + " -1 - Not paranoid at all\n" + " 0 - Disallow raw tracepoint access for unpriv\n" + " 1 - Disallow cpu events for unpriv\n" + " 2 - Disallow kernel profiling for unpriv\n"); +} + void trace_event(union perf_event *event) { unsigned char *raw_event = (void *)event; diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 93516cf4682c..fd53db47e3de 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -36,5 +36,6 @@ int ui_helpline__show_help(const char *format, va_list ap); #endif void ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); +void ui__warning_paranoid(void); #endif /* __PERF_DEBUG_H */ diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2b15c362ef56..1023f67633a4 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -710,7 +710,7 @@ try_again: * in the whole kernel symbol list. */ if ((long long)al->addr < 0 && - cpumode == PERF_RECORD_MISC_KERNEL && + cpumode == PERF_RECORD_MISC_USER && machine && mg != &machine->kmaps) { mg = &machine->kmaps; goto try_again; diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py index e24ffadb20b2..bbc982f5dd8b 100644 --- a/tools/perf/util/setup.py +++ b/tools/perf/util/setup.py @@ -1,13 +1,18 @@ #!/usr/bin/python2 from distutils.core import setup, Extension +from os import getenv + +cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] +cflags += getenv('CFLAGS', '').split() perf = Extension('perf', sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'], include_dirs = ['util/include'], - extra_compile_args = ['-fno-strict-aliasing', '-Wno-write-strings']) + extra_compile_args = cflags, + ) setup(name='perf', version='0.1', diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 17df793c8924..f06c10f092ba 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1196,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, if (curr_dso == NULL) goto out_elf_end; curr_dso->kernel = self->kernel; + curr_dso->long_name = self->long_name; + curr_dso->long_name_len = self->long_name_len; curr_map = map__new2(start, curr_dso, map->type); if (curr_map == NULL) { @@ -1842,6 +1844,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map, if (fd < 0) return -1; + dso__set_long_name(self, (char *)vmlinux); dso__set_loaded(self, map->type); err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); close(fd); @@ -2403,6 +2406,8 @@ int symbol__init(void) if (symbol_conf.initialized) return 0; + symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64)); + elf_version(EV_CURRENT); if (symbol_conf.sort_by_name) symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - |